How to create infinitive random platform in endless running game? - libgdx

I'm making a 2d endless running game. I have a platform that is formed by many blocks. Every block has one of three color: red, blue, green. I don't know exactly how to random blocks with different color at runtime. I have used an array to store block rectangles like the example Drop(Simple game) on wiki page. In render class I have this code to change color of block at runtime:
public void drawBlock() {
TextureRegion region = new TextureRegion();
for (Rectangle rec : colorBlock.getBlocksRec()) {
if (colorBlock.isRed()) {
region = red;
}
if (colorBlock.isGreen())
region = green;
if (colorBlock.isBlue())
region = blue;
batch.draw(region, rec.x, rec.y, rec.width, rec.height);
}
}
But it seems to be failed because it changes all blocks on screen into one color at the same time.
I also have some problems in making blocks move continuously. They moved but they looked like hundred of blocks overlapped each other. I don't know how to control the blocks in the right way. I used TimeUtils for check when the next block should be created, but it was totally failed.

You can use an Array or your ground blocks that adds a new one when it about to appear on the screen, and removes the oldest entry when it will not be seen on the screen anymore. I had a similar question, check it out: HERE
For random colors you can use the MathUtils.random(float f) when you about to add a new block to the array.
For example something like this, or with switch :
float res = MathUtils.random(8f);
//this returns a random float between 0 (inclusive) and 8 (exclusive)
if(res <= 2) { //[0-2]
//add green
}
if(res > 2 && res <= 5){//(2-5]
//add blue
}
if(res>5){//(5-8)
//add red
}

Related

Send all instances of a container BEHIND everything else?

Found this topic: AS3 setChildIndex to front I'm trying to accomplish the exact opposite.
"addChildAt" doesn't work for me when I'm setting the container behind everything else or something along the lines. And as for stars themselves, I can't send them back anymore than layer 0 for some odd reason (it'll give me error 2006, stating "The supplied index is out of bounds"). Here's the code:
starsSpawn function:
var starContainer:MovieClip = new MovieClip();
addChildAt(starContainer, 20);
starContainer code:
function starsSpawn()
{
for(var i:int= 0; i < 30; i++)
{
var newStar = new starCode();
var scaleXY = Math.random()*(2)+0.1;
newStar.width = scaleXY;
newStar.height = scaleXY;
var positionX:Number = Math.random()*(stage.stageWidth + (1* newStar.width));
var randomY:Number = Math.random()*(stage.stageHeight - newStar.height);
newStar.x = positionX;
newStar.y = randomY;
starContainer.addChild(newStar);
}
}
Essentially how it works is that a container is set up and the for loop creates 30 stars, each with the outlined code.
When you addChildAt(myChildMC, 0); it gets added at index 0 and everything else gets bumped up. Z order indexes in AS3 are contiguous, meaning every space from zero to the highest z order must be filled. If I remove whatever is on layer 4, layer 5 will slide down to fill, and so on
And I don't think you can add something to index 20 unless all the other indexes have children in them. That may be what is causing your particular error. To add something to the top level just do addChild(myChild).
edit
Since it sounds like you have the concept of how z-order works in reverse in your mind, you probably are wanting to have the stars "in front" of everything else i.e. Always on top i.e. Always visible. To do that just do addChild(starsContainer) after all the other containers are added or Sprites or MovieClips. If you add something to the stage at runtime, just add the stars container again (this won't create a second container, it literally just changes the z-order if there is already a container by that name... this is an often misunderstood point).

move in move out tween animation for group of movieclips using as3

I have set of 6 movieclips as array_0 and another set of 6 movieclips as array_1. It is like two choices for different screens. Both these arrays are nested in another array as all_array. all 12 movieclips are positioned to a same x and y at initial load and that is outside the visible stage. I would like to use two different global variables for indexing. for example, cCat_Sel which ranges from 0-5 and another cScr_Sel ranges from 0-1. cCat_Sel will be changed on a click event of six buttons separate objects on stage (each button for each category).
so it will show the content for each category as per the value of cScr_Sel. if cScr_Sel is 0 then it will use all_array[0][cCat_Sel] to access the current target and similarly respective array for value of 1 as all_array[1][cCat_Sel]
I have done all the work including all tween animations to move current target and make it visible. But the tween does not bring the second set of mcs to visible area. I have two functions one for movein and one for move out by using tween animation for mc.x property. every relevant click event; I have to move current mc out and make alpha 0 and once that is finished, move in new current target and make alpha 1.
Somehow I have to combine these two tweens in one function. This is the part that I am stuck. or may be putting these mcs in two different arrays not a correct approach. I can easily achieve what I want on Enter Frame event of the root to check for cCat_Sel and cScr_Sel variables and do both animations one after the other but it seems like enter frame uses too much of cpu and makes it slower and probably not preferable.
willing to try anybody's suggestions or guidance. Thanks in advance.
I do not have any formal or informal programming education at all but I make things work by reading and trying out few things as per stackoverflow question and answers and sometime google. because most of my answers I have found from stack overflow.
Update:
function fnSlideInOut(cMc:Object, pMc:Object){
var HideX:Number =650;
var ShowX:Number = 0;
if(cMc != null){
if(cMc.x != ShowX){
//cMc.alpha = 1;
var SlideMcIn:Tween = new Tween(cMc, "x", Strong.easeOut, 650, ShowX, 0.5, true);
SlideMcIn.addEventListener(TweenEvent.MOTION_FINISH, fnSlideInFinish);
SlideMcIn.start();
}
}
if(pMc != null){
if(pMc.x != HideX){
//pMc.alpha = 1;
var SlideMcOut:Tween = new Tween(pMc, "x", Strong.easeOut, 0, HideX, 0.5, true);
SlideMcOut.addEventListener(TweenEvent.MOTION_FINISH, fnSlideOutFinish);
SlideMcOut.start();
}
}
function fnSlideOutFinish(e:TweenEvent){
//SlideMcOut.obj.alpha = 0;
SlideMcOut.removeEventListener(TweenEvent.MOTION_FINISH, fnSlideOutFinish);
}
function fnSlideInFinish(e:TweenEvent){
//SlideMcIn.obj.alpha = 1;
SlideMcIn.removeEventListener(TweenEvent.MOTION_FINISH, fnSlideInFinish);
}
}//End Function
fnSlideInOut(cScr_Sel, pScr_Sel);
I would like expert like you to comment on any kind of errors for the above code. It works 99 times but 1 time the movieclip either does not reach the destination or current and previous both targets showing and that too not where they are suppose to. This only happens when button click event happens in a quick succession. Thanks again
A option could be to use a third party library like TweenLite. It will then make it easy for you to run your second animation right after the first one is complete:
private function startAnimation():void
{
var mcToHide:MovieClip = all_array[cScr_Sel][cCat_Sel];
TweenLite.to(mcToHide, 1, {x: HIDDEN_X_POSITION, y:HIDDEN_Y_POSITION, alpha:0, onComplete:finishAnimation});
}
private function finishAnimation():void
{
var mcToShow:MovieClip = all_array[(cScr_Sel + 1) % 2][cCat_Sel];
TweenLite.to(mcToShow, 1, {x: VISIBLE_X_POSITION, y:VISIBLE_Y_POSITION, alpha:1});
}
You can then call startAnimation() on a relevant mouse click event and after having set cScr_Sel and cCat_Sel accordingly to your needs.

How can I randomize a picture under a cover in actionscript 3.0?

I'm making a flash game for practice and I have my stage set up so there are 9 boxes. When the game is started, one of the boxes is randomized as the one with the start underneath, if you pick the box with the star underneath, you win.
The randomizing code is
var star = 1 + Math.Round(Math.Random()*8.0)//generate a number between 1 and 9
What i dont know is how to attach this code so that it assigns the star to one of my 9 boxes made as buttons. How can I hide the star underneath the box as a cover.
Thanks for your time
I'm picturing one of those games where you but a ball under one of three cups and swap the cups, then guess which one has the ball.
The simplest way to hide one object under another is to just add it to the stage before the object covering it. So add your star to the stage, then add all your boxes. BUT since you don't have to have an unseen object actually be on the stage, I recommend not adding the star to the stage until it is revealed, and remove it when it gets hidden again.
You can create layers to make sure objects are always above/below what they need to be above/below. Create sprite objects, and call them layers. Add them in order from bottom to top. Add other sprites to these layer sprites to control their display order.
var layer1:Sprite = new Sprite(); // Bottom / background
var layer2:Sprite = new Sprite(); // Top / foreground
stage.addChild(layer1);
stage.addChild(layer2);
layer2.addChild(someObject1);
layer1.addChild(someObject2); // someObject2 will be below someObject1
That deals with covering the star with the boxes.
You can put your boxes in an array. You'll want a number between 0 and 8, then just use that as the index in the array to get the box you want.
var whichBox:int = (int)(Math.random() * 9);
var boxesArray:Array = new Array();
for (var i:int = 0; i < 9; i++) {
boxesArray.push(new Box()); // Or whatever your boxes are
}
var boxWithStar:Box = boxesArray[whichBox];
You can then move the star to the same location as its box...
star.x = boxWithStar.x;
star.y = boxWithStar.y;
This is a pretty handy function you can use:
function randRange(start:Number, end:Number) : Number
{
return Math.floor(start +(Math.random() * (end - start)));
}
example (any number between 0 - 9) :
var random:int = randRange(0,9);
remember to make it an int or you may end up with a float.

Ideas for jumping in 2D with Actionscript 3 [included attempt]

So, I'm working on the basics of Actionscript 3; making games and such.
I designed a little space where everything is based on location of boundaries, using pixel-by-pixel movement, etc.
So far, my guy can push a box around, and stops when running into the border, or when try to the push the box when it's against the border.
So, next, I wanted to make it so when I bumped into the other box, it shot forward; a small jump sideways.
I attempted to use this (foolishly) at first:
// When right and left borders collide.
if( (box1.x + box1.width/2) == (box2.x - box2.width/2) ) {
// Nine times through
for (var a:int = 1; a < 10; a++) {
// Adds 1, 2, 3, 4, 5, 4, 3, 2, 1.
if (a <= 5) {
box2.x += a; }
else {
box2.x += a - (a - 5)*2 } } }
Though, using this in the function I had for the movement (constantly checking for keys up, etc) does this all at once.
Where should I start going about a frame-by-frame movement like that? Further more, it's not actually frames in the scene, just in the movement.
This is a massive pile of garbage, I apologize, but any help would be appreciated.
try doing something like: (note ev.target is the box that you assigned the listener to)
var boxJumpDistance:Number = 0;
function jumpBox(ev:Event){
if (boxJumpDistance<= 5) {
ev.target.x += boxJumpDistance; }
else if(boxJumpDistance<=10){
ev.target.x += boxJumpDistance - (boxJumpDistance - 5)*2
}
else{
boxJumpDistance = 0;
ev.target.removeEventListener(Event.ENTER_FRAME, jumpBox);
}
}
then instead of running the loop, just add a listener:
box2.addEventListener(Event.ENTER_FRAME, jumpBox);
although this at the moment only works for a single box at a time (as it is only using one tracking variable for the speed), what you would really want to do is have that function internally to the box class, but im unsure how your structure goes. the other option would be to make an array for the boxes movement perhaps? loop through the array every frame. boxesMoveArray[1] >=5 for box 1, etc.

swing: JSlider but with coarse/fine controls?

I have a JSlider with 65536 different values. It works great for coarse adjustments and for very fine adjustments (+/-1 using up/down arrow) but is very poor in the middle.
Is there anything out there that would be better? I can vaguely imagine taking 2 sliders one for coarse + fine adjustments, but can't really figure out how to get them to work together.
What about using a JSpinner instead of a JSlider? With a SpinnerNumberModel, you can set the step size and even change the step size dynamically.
If you're OK with having multiple controls, you could even have two spinners, one for setting your values and another for setting the step size that is used by the first spinner.
For an example of this, I took the SliderDemo code from the Swing slider tutorial and modified it instead to use two JSpinners instead of a single JSlider. Here's the most interesting part of the code that I changed:
//Create the slider^H^H^H^H^H^H spinners.
// JSlider framesPerSecond = new JSlider(JSlider.HORIZONTAL,
// FPS_MIN, FPS_MAX, FPS_INIT);
final int initStep = 1;
final SpinnerNumberModel animationModel = new SpinnerNumberModel(FPS_INIT,
FPS_MIN,
FPS_MAX,
initStep);
final SpinnerNumberModel stepSizeModel = new SpinnerNumberModel(initStep,
1,
10,
1);
final JSpinner framesSpinner = new JSpinner(animationModel);
framesSpinner.addChangeListener(this);
final JSpinner stepSpinner = new JSpinner(stepSizeModel);
stepSpinner.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent arg0)
{
animationModel.setStepSize(stepSizeModel.getNumber());
}
});
I also had to make a bunch of less interesting changes, such as creating a label for the step size spinner, adding the new label and new spinner to the container, and changing the stateChanged() method on this to cast the source of the event to a JSpinner instead of casting it to a JSlider.
You could, of course, elaborate on this further, such as increasing the step size for the step size spinner (for example, so that you can change the step size from 1 to 101 in a single click). You could also use a different control instead of a JSpinner to set the step size, such as a combo box.
Finally, to make this all really easy to use, you would likely want to hook up some keystroke accelerators (possibly through a menu?) so that you could change the step size without actually moving the mouse or the keyboard focus from one spinner to another.
Edit: Given that you have to use a JSlider no matter what, are you aware that you can use PgUp/PgDn to move up and down by 1/10th of the total range?
If you want to change that 1/10th amount (such as making it dynamic), then you'll need to override the the method BasicSliderUI.scrollByBlock().
Here's an example where I just overrode the UI class of a JSlider to step by 1/4th of the range, instead of 1/10th:
//Create the slider.
JSlider framesPerSecond = new JSlider(JSlider.HORIZONTAL,
FPS_MIN, FPS_MAX, FPS_INIT);
framesPerSecond.setUI(new javax.swing.plaf.metal.MetalSliderUI() {
private static final int SLIDER_FRACTION = 4;
/**
* This code is cut, paste, and modified from
* {#link javax.swing.plaf.basic.BasicSliderUI#scrollByBlock(int).
* I should be ashamed of cutting and pasting, but whoever hardcoded the magic
* number "10" in the original code should be more ashamed than me. ;-)
*
* #param direction
* either +1 or -1
*/
#Override
public void scrollByBlock(final int direction) {
synchronized(slider) {
int oldValue = slider.getValue();
int blockIncrement = (slider.getMaximum() - slider.getMinimum()) / SLIDER_FRACTION;
if (blockIncrement <= 0 && slider.getMaximum() > slider.getMinimum()) {
blockIncrement = 1;
}
int delta = blockIncrement * ((direction > 0) ? POSITIVE_SCROLL : NEGATIVE_SCROLL);
slider.setValue(oldValue + delta);
}
}
});
From here, it wouldn't be too hard to replace that constant SLIDER_FRACTION with a variable that was set by another slider or by a spinner, would it?