How to remove something once drawn? - libgdx

I'm using libgdx and recreating pac-man, I'm currently using this code to spawn in the pellets for the level (essentially they spawn everywhere that the walls and Pac-Man aren't)
for(int x = 1; x < 27; x++) {
normalPellet.setX((x * 70) + 25);
normalPellet.setY((y * 70) + 25);
if(!(normalPellet.overlaps(walls)) {
batch.draw(pellet,normalPellet.x,normalPellet.y);
pelletCount++;
}
}
My problem is that I don't know how to make it so that when Pac-Man moves over the pellets they get "eaten" and are removed from the field. When Pac-Man moves over them, they do disappear, but as soon as Pac-Man moves to a different place on the map they immediately reappear. How do I make it so they go away permanently?

Typically a game is redrawn on each render call (the render loop). Your game runs by calling your root render() method repeatedly. At the beginning of your render method, you clear the screen, and then draw everything again. So to remove something, you simply stop drawing it.
You need to create a List of all active pellets. This can be a list of some Pellet class that you create that has coordinates and any other state data that is relevant to your game (such as whether it's a "super-pellet"). Or it could just be a list of Vector2s if all your pellets are identical so the only thing you need to track is their position.
When a round starts, you should create all the pellets you need at the coordinates they should be at and add them all to the List.
Then, instead of doing your for(int x = 1; x < 27; x++) loop to draw them, you should loop through your list instead and draw each pellet based on its position (and possibly other data, for example if there are super pellets, you could choose how big to draw it based on that data).
When the character moves, you can check its overlap with each pellet in the list. When a pellet is overlapped, you can remove it from the list and update your score. When it is removed from the list, it will no longer be drawn in the other part of your code where you loop through the list to draw them.

Related

Rotation issue While Reflected (2D Platform Game)

My player's arm is programmed to follow my mouse and rotate accordingly and I've programmed bullets to be fired using this rotational value
(Math.atan2(this._dy, this._dx) * 180 / Math.PI
where _dy is the y location of the mouse (-) the y of my player's arm and the _dx is the x location of mouse (-) the y of my player's arm.
However, when I program the player to reflect when the mouse has crossed the x-coordinates, the bullet angle is also reflected. How would I fix this issue?
I've already tried subtracting 180 from the angle but it still doesn't fire towards the direction of the mouse.
First, make sure you have this parent-child-sibling relationship:
"A" should be the parent of "B" and "C". "B" and "C" should have no direct link. Their connection is that they have the same parent. So when you want to move the character, move the parent, and both will move. Now, for the good stuff:
Use key frames and sibling relationship
beginner level approach
Make the character and the arm both children of the same parent display object container (Movie Clip in this case). Now, instead of flipping anything by xScale, which I assume you did, you can just have both MC children (arm and character) go to frame 2 (or whatever is available) where the graphics are flipped.
xScale body, move arm to frame 2, change z order
moderate level approach (best result)*
Alternatively, you could do that same "sibling" setup as above, and then scale the character but not the arm (I think scaling the arm will mess it up again, but you could have the arm go to frame 2 and have it drawn reversed so the thumb and handle are pointing the right way. Bonus points for changing the z stacking order so the arm goes to the other side of the body. xScale for only the body allows you to only have one set of frames for animation of his legs and torso etc. but also avoid scaling the arm at all).
Global properties
advanced approach
A third option is to use global rotation and global points. I won't illustrate that here because I'm not that advanced and it would take me a while to figure out the exact syntax. If you already have mastered global properties, try this; if not, try one of the ones above.
* Example (best result)
if (facingRight == true && stage.mouseX < totalChar.x){
// totalChar is on the stage
// and contains two children:
// armAndGun and bodyHeadLegs
totalChar.armAndGun.gotoAndStop(2);
// in frame 2 of the arm MC, draw the
// arm and gun in the flipped orientation
totalChar.addChild(bodyHeadLegs);
// re-ads body to parent so it's
// z-order is above the arm;
totalChar.bodyHeadLegs.xScale = -1;// flips body and any animation of legs and head
facingRight = false;
// use a variable or property like this
// to keep him from constantly flipping
}
You'll need similar code to flip him back the other way.

Collision Detection - How to?

I am currently working on a flash game and am rather new to AS 3 or flash. Need some advice in how to implement one of the core elements of my game.
The idea is 2 player competitive snake style game, only the players do not try to kill each other, but try to reach their opponents spawnpoint.
1 of the key parts of the game would be a grid which is created over the stage where either player may use to "Create walls" by passing through points on the grid. I have no idea how to implement this. Currently I have the basics down where there are 2 players with a starting spot, and if either one reaches the other's starting zone, they score a point.
I need some advice in how to go about implementing this feature:
Each point in the grid will start off in a certain state, and when a player passes through that point, it will be "activated". Then the player may move through any adjacent points to the "activated" point, which will generate a wall between both active points, and thats how they will create mazes to protect their starting area.
Should I generate each point individually or create a grid with a simple function:
//function to create grids on the map
public function createGrid()
{
var rows:int = 6;
var cols:int = 11;
for (var py:int = 0; py < rows; py++) {
for (var px:int = 0; px < cols; px++) {
this.grid = new griDot(player1,player2, this);
grid.x = 50 + grid.width + 100 * px +10;
grid.y = 50 + grid.height +100 * py + 10;
this.addChild(grid);
}
}
}
and they are detected with this function(don't laugh i'm pretty noob):
public function checkDotCollision(player)
{
if(player1.hitTestObject(grid) == true)
{
trace("player dot collision detected");
}
if(player2.hitTestObject(grid) == true)
{
trace("player dot collision detected");
}
}
currently only the left most bottom square of the grid is detecting the player. Any help / advice on how to implement this feature would be greatly appreciated.
I'm not going to provide you with code, just with an idea.
In your Player class (if you don't have one, you can get away with the dynamic properties of a movieclip but it's not very clean), add a lastTouchedGriDot of type griDot.
In checkDotCollision, check for each tile. You can't do this at the moment; looks like you'll have to maintain a collection for griDots somewhere. So alter createGrid() to store the created objects in a collection of sorts. Then we can check for each tile. So do so. If you've found a hit, do the following:
If there is no last touched grid point, set the last touched grid point to the one you're touching now.
If the grid point that was last touched is the same as the one you're touching now, do nothing.
If the grid point that was last touched is different than the one you're touching now, check if it's adjacent. If so, build a wall. If not, set the last touched grid point to the one you're touching now.
This should provide you with a solid start. You'll have to add wall collisions and checking if there already IS a wall yourself.

Flash Games: Make a world continuous, circular

I am writing now a flash game and I run into a an issue. I have a map for the game which is defined as a 2-D array, where each element represents a component of the map. The player is always in the center of the map.
The problem is when the player reaches one end of the map. Now it is empty space. I want that the player instead of seeing the empty space, to see another end of the map and in this way, the map will loo like it goes around.
So for example if the player goes to right he will eventually start seeing the the left side of the map and the world will look continuous.
Does anyone knows how to implement this functionality?
You could make the array 2 times and put the first one behind the second one again and than the second one behind the first etc etc..
It's done here with 2 pictures, just use the arrays instead:
//The speed of the scroll movement.
var scrollSpeed:uint = 2;
//This adds two instances of the movie clip onto the stage.
var s1:ScrollBg = new ScrollBg();
var s2:ScrollBg = new ScrollBg();
addChild(s1);
addChild(s2);
//This positions the second movieclip next to the first one.
s1.x = 0;
s2.x = s1.width;
//Adds an event listener to the stage.
stage.addEventListener(Event.ENTER_FRAME, moveScroll);
//This function moves both the images to left. If the first and second
//images goes pass the left stage boundary then it gets moved to
//the other side of the stage.
function moveScroll(e:Event):void{
s1.x -= scrollSpeed;
s2.x -= scrollSpeed;
if(s1.x < -s1.width){
s1.x = s1.width;
}else if(s2.x < -s2.width){
s2.x = s2.width;
}
}
You simply check if your player is about to get off the "right" or "left" edge of the map, and position him at the other edge. To draw a circular map, you can use the following technique: if you are about to draw a column of a number that exceeds the map's width, decrease that number by width and draw the column at resultant index; and if you are about to draw a column at index below zero, add width and draw the column at resultant index. If you are in troubles of making a hitcheck at continuous map's borders, you can employ the same trick to find neighbors. (The "circular array" is a pretty basic algorithmic problem, and is resolved in many ways already)
You have a few options here. You can do the pac-man style of just making your character pop up on the other side of the screen, but that would require you to abandon the cool bit of the character being in the middle at all times.
On to the real suggestions:
If you're not implementing your array as one solid object (i.e. making it draw individual collumns/rows at a time) then this is a no-brainer. Just have a function that returns the index of the next collumn/row, within certain bounds. Like, if your array is 40 elements wide, when it tries to draw element 41, subtract the size of the array, and make it draw element 1 instead.
If your array is one solid object (like if you drew it onto a stage object and are just manipulating that) and it's not very big, you could probably get away with drawing a total of four of them, and just having a new one cover up any whitespace that's about to appear. Like, as you approach the right edge of the first array, the second array moves to the right of it for a lawless transition.
If your array is a solid object and is very big, perhaps you could make eight buffer objects (one per edge and one per corner) that hold approximately half a screen's worth of the array. That way as you approach the right edge, you see the left edge, but then when you cross into the buffer zone, you could teleport the player to the corresponding position on the left of the array, which has the buffer for the right size. To the player, nothing has changed, but now they're on the other side of the world.

Make a turn based system like final fantasy tactics AS3

i wanted to make a turn based system like final fantasy tactics. I already created the map, which is 5x5 tiles grid and the characters which is each character places in the end of the tiles. I have 2 teams, which are named Red and Yellow.
------Red-------:
First character is at 0,0. Second character is at 0,1. Third character is at0.2, fourth character is at0.3, and the last one is at0.4`.
-----Yellow------:
First character is at 5.0. Second character is at 5.1. Third character is at 5.2, fourth character is at 5.3, and the last one is at 5.4.
I wanted Red team are moving first and make a decision (whether it is attack or wait), and after 5 characters of the Red team is already made a decision, the Yellow team is the one that make a decision (Yellow team is an AI)
But, i don't know how to move my characters into the next grid (e.g: from 0,0 to 0,1) by clicking the left mouse button and also how do i display a grid (when select a move selection) that shows how many tiles that the character able to move.
Anyone know about this? or how should i know more about this? is there any recommendations books or webs?
You have your basic data structures set up, but now you need to get some higher level code to manipulate that data.
First of all, I think you should work on selecting locations on the grid with the mouse. Once you can click and get that grid coordinate saved to a variable, you need to set up a function to move your characters. After the first click (on a character), you need to check the valid moves, and for each valid move, you need to render an image on the grid square (or highlight the square's texture).
Secondly, you need a function which iterates through all the characters in each team, according to who moves next. When you have gone through Red.length (red is an array consisting of each player), then you switch to counting through Yellow.length, and running the AI for each character. If you are trying to make a two player game, you instead ask for user input a second time for the yellow team.
I recommend that you learn about how to display your grid and set up a simple way to highlight squares on the grid. After that, you need to convert mouse coordinates into grid coordinates. Your teams should each be an array of characters. I'm not familiar with actionscript, but in the languages I know, they would look like this:
team[6] = {Character1, Character2, Character3... }
Character1.position = {x, y}
running a turn would be something like this:
while battle == not finished {
for (i = 0; i < red.length; i++) {
getInput();
move(red[i], newX, newY); //red[i].position = {newX, newY}
}
for (i = 0; i < yellow.length; i++) {
runAI();
move(yellow[i], newX, newY);
}
}
The hardest part will be the mouse selection and drawing the grid/characters. Graphics are always a nuisance. The data itself just takes a bit of thinking. Your question in particular seems to be about game programming. My advice is to make the grid, then figure out how to display the grid. Then get mouse input. Finally, worry about moving the characters and highlighting squares.

MovieClip alignment (a character with multiple states) without using a meta-MovieClip

I'm working on a game where there are 4 characters on screen, each with several different states and corresponding MovieClips so that my library looks a little something like this:
Character 1:
IdleAnimation
SleepAnimation
..
Character 2:
IdleAnimation
SleepAnimation
..
Each animation (provided by a 3rd party) has a different anchor point, so when character A is at position 100, 100 on screen and moves from the idle to sleep animation he suddenly jumps 20 pixels to the right due to the anchor point.
Usually I would store all the different states in one MovieClip in separate frames and manually adjust the position of each one til they matched up, however I am also trying to port this to Android and therefore must keep the number of children on screen at once to a minimum.
Is there anything else I can do other than store offset x and y values for each character and each animation, and simple set the x/y via code whenever their state changes?
To keep the numChildren down I guess you have no choice
but to keep track of x- and y-offsets of the animations of each character
stored perhaps in an Object variable of form { state: registration_point }.
Then when changing states you can set the registration point
through this method by Emanuel Feronato:
http://www.emanueleferonato.com/2010/08/04/changing-a-movieclip-registration-point-on-the-fly-with-as3/
An idea to try though is to simply place the registration point to the center of each animation state:
var reg_x:Number = mc.width / 2;
var reg_y:Number = mc.height / 2;