Best way to draw collectibles in a game? - java

I want my game to draw coins from a sprite and then my main character would be able to pick them up. I'm trying to use array list for this but i have no idea how to implement this feature. Do I make an array list of Sprites I need to draw and then reuse it ? If so , how ?
Or do I use some other function ? I'm a begginer , so sorry if this question seems odd .

I recommend using Libgdx's Array class instead of a Java ArrayList, as it is optimized for game performance.
Create an Array to hold all the active coins.
Array<Sprite> activeCoins = new Array<Sprite>();
Then create a coin pool. A pool is a helper for creating copies of something without causing garbage collection hiccups. You need to make a subclass of Pool to use. It describes how to create a new coin when one is needed.
public class CoinPool extends Pool<Sprite> {
TextureRegion coinTextureRegion;
public CoinPool(TextureRegion coinTextureRegion){
this.coinTextureRegion = coinTextureRegion;
}
protected Sprite newObject(){
return new Sprite(coinTextureRegion);
}
}
Then create an instance of CoinPool to use in your game.
Now whenever you want a new coin, pull one from the pool. It will only instantiate a new one if necessary. Otherwise, it will hand you a recycled one from earlier. And once you get it, set it's position and other parameters wherever you want it. Keep in mind it might still have old values attached to it, so if you are rotating your coins and moving them around or changing color, you'll want to be sure you reset position and rotation, and color.
Sprite newCoin = coinPool.obtain();
newCoin.setPosition(x,y,z); //as desired
newCoin.setRotation(0); //if you are rotating them
newCoin.setColor(Color.WHITE); //if you have been changing their color
activeCoins.add(newCoin); //Add your new coin to the list of active coins
And whenever you are done with a coin (when it has been collected), you need to remove it from the active coins list and return it to the pool:
for (Sprite coin : activeCoins){
boolean grabbed = isCoinGrabbed(coin); //however you want to do this
if (grabbed){
coinGrabbed(); //whatever you want to happen when a coin is grabbed
activeCoins.remove(coin);
coinPool.free(coin); //return it to the pool
}
}
And to draw them, you can just submit all the sprites currently in the activeCoins list to the sprite batch.

I recently designed a game in Java that was a 2D side scrolling role playing game. Part of the game was to walk around and pick up items like swords and armor.
The way that I accomplished loading the sprites to my game was to give a JLabel my image (which was retrieved locally on start of the game) by setting it's icon to the image.
Next I would randomly place my JLabel on the game map. I didn't use an array list, although you could if you had multiple types of swords, or coins, etc.
The array list could contain types of swords (JLabel's with their icon set to a sprite) such as a bronze, silver, and a gold sword.
Once your JLabel('s) is loading to your map you can give them a hit box and if your character moves inside the hit box then remove the JLabel from the map and into the players backpack (or whatever it is, maybe append a coin amount?).

Related

How to call update method on one particular sprite from an ArrayList of Sprite objects created in Slick2D for a game?

I am using Slick2D to make a simple game with a number of sprites. There is a player sprite which will push other object sprites around the map.
I have used an ArrayList to store all the sprite types created, but when I use the player to push a particular type of sprite (for example a wooden block) all the occurrences of that particular sprite type in that map gets updated as well. How do I specify to update that one particular wooden block rather than updating all the wooden blocks loaded in the game?
ArrayList:
private ArrayList<Sprite> sprites;
Creating all the sprites and storing them inside the ArrayList:
public static ArrayList<Sprite> loadSprites(String filename) {
ArrayList<Sprite> list = new ArrayList<>();
/*bunch of code to load the sprite*/
list.add(World.createSprite(name, x, y));
return list;
}
here types is a 2D array where I am storing all the names of the sprites according to their map coordinates, which I am getting from a csv file.
public static Sprite createSprite(String name, float x, float y) {
switch (name) {
case "player":
return new Player(x, y, "player");
case "wood":
return new Wall(x, y, "wood");
case "tile":
return new Floor(x, y, "tile");
case "wall":
return new Stone(x, y, "wall");
case "metal":
return new Target(x, y, "metal");
}
return null;
}
Thanks in advance. :)
What you need to do is to identify the object the player pushes. Let's assume you have three sprites in your list all of the type wood. From what you wrote in your question it seems like if the player starts pushing obviously all sprites get updated as well because either:
Your program can't determine what sprite exactly is supposed to be pushed.
Your program knows what sprite is supposed to be pushed but cant determine what sprite to update visually (hard to tell with your provided code)
So what you should do is to ensure that the pushing action is only performed to the object/sprite the player is interacting with. You need to have constraints to check for this interaction this constraint might be pushing a button or intersecting with that one particular sprite / object. So you could do for example the following:
Iterate through your arraylist and check with which object/sprite your player is intersecting.
If there is an intersection with an object of your list you exactly know what object that is and you could call the update, push or any other method on the object.
If you have more than one possible candidate to update you need to specify your search, for example you could only interact with objects / sprites your player is looking at.
Call the needed method of that particular one object (eg. push()).
What also might be a solution is that you should be sure about your game architecture. By this I mean that you should be certain about how your game is internally designed. Generally each gameobject in your game should have sprite and maybe a sound or certain other attributes. By this you make sure that each object has a specific sprite just for itself, so you wont get into trouble with updating any other sprites because you only can access this specific sprite by this specific object. So maybe you should consider not iterating over a list of sprites but rather iterate over a list of gameobjects in your world (I'm not sure but maybe a sprite is a gameobject for you, but a sprite is just the graphical representation of a gameobject.). Check for interaction with each of these gameobjects and in case perform a specific action. Such code could look like the following:
//inside the update method of your player
for(GameObject gameObject : world.getAllGameObjects()){
if(player.getHitbox().intersects(gameObject.hitbox())){
gameObject.update() //push, update sprite, whatever
}
}
Checking for intersection is only one solution as I already said you could also check for the pressing of a key or for a certain distance. From my understanding what is important for you is the identification of a single object and to update that single object.
It's hard to tell what exactly your problem is because I dont have insight in your entire code, but if you ensure to find the right object to interact with and also making sure that only this object is graphically updated this will work.
Beside the architecture it self the problem might be here:
if (Loader.getSpriteOfType("wood", Player.getPlayerX() - 1, Player.getPlayerY())) {
dir = DIR_LEFT;
}
I'm not sure what Loader.getSpriteOfType(..) does since I don't know how sprites or objects are entirly stored and handled in your game cycle, but I'd assume that it returns all (not only a specific one) sprites of type "wood" because it's searching for "wood" and finds all objects which "wood", but you want only the exact one which your player is interacting with so maybe you should be more specific in that if-clause (just an assumption though since I don't know your code).
Hope this helps you and gives you something to think about.

Interchanging objects in 2d Arrays

I'm creating a Pacman clone in JavaFX, but actually the language shouldn't matter at all, it's more about the logic behind it which I can't figure out.
I've taken a video of the issue, it illustrates quite well what bug I'm facing.
I want that the Player can eat a Food (eg. the Food gets deleted from the board[][] and the score is increased). This works. But I also want the Ghosts not to be able to eat the Food, but my draws are all based off of the board[][], so I can't have a Ghost and a Food at the same place.
Not sure how it should be done, my thought was that I can create a holdingObject variable which "holds" the Food object and which is then placed back to where it came from when the Ghost moves further.
My GameView has these two important fields in it:
private static GameObject board[][];
private static LinkedHashSet<Moveable> moveableLinkedHashSet;
Both variables get filled by other methods, these work fine.
The following code block seems to contain the issue, although it may also have to be dealed with in the Line #89 (see link below).
private void executeMoveWithPosition(Position positionDest) {
GameObject ghost = this;
// TODO: Fix holding object. Currently it's a mess:
// TODO: Two consecutive foods won't be handled correctly, food gets set to wrong position at the beginning
// holdingObject gets set to the current position - possibly null, that's ok
LevelManager.getBoard()[position.getX()][position.getY()] = holdingObject;
// ghost gets inserted at the new position
LevelManager.getBoard()[positionDest.getX()][positionDest.getY()] = ghost;
// holdingObject gets emptied
holdingObject = null;
// actually move the ghost
position.setX(positionDest.getX());
position.setY(positionDest.getY());
}
Ghost.java, from which I removed methods and if clauses which didn't matter for this.
If I understand correctly, you simply don't know what data structure you should use to represent your game board, including the player, enemies and items (food).
Without investigating your code in detail, I would suggest...
You create a Tile class. The board can then be made up of those. It can save information on whether it is a traversable or not and could also hold the item that is placed upon it.
Your enemies already have a class (Ghost) that holds their position, so just make sure you have a collection of enemies that you can iterate over for rendering and game logic. This way, you don't need the board to keep track of these itself.
Optionally, have an Item (or Food) class, that you handle just like your enemies: they hold their position and you keep all of them in a collection. Again, the Tiles then don't need to keep track of these anymore.
In order to figure out if there is a Ghost or Food on a Tile, you would then need to iterate over all of these and check their position. For a game with such a small and simple level, this should be no issue.
Of course, there are other solutions and ultimately only you can know which one fits your project.
EDIT: As it turns out after exchange of some comments, solving the problem at hand was as easy as just not putting the Ghosts into the board array, as they do hold their own position. The above covers that plus is a bit more general and broad and should hopefully apply to others with similar issues as well.

putting multiple objects into a arraylist and draw them

I have just learned to use arraylist so be nice :P .
I wonder how i can put a few objects (like a circle or a square) into the arraylist and draw them out on a jpanel so all of them stay. I know how to draw one thing but i'm trying to make a game and would like to have multiple things drawn at the same time.
All answers appreciated!
I dont femiliar with JPanel and swing but a bsic algorithm will be:
add all the wanted objects to arraylist (or an other data stracture)
Start Loop
for every item on the data stracture - item.Draw
update all locations
return to loop start

Java Collision Detection Not Working

I have made threads in the past about similar questions but because of my lack of detail the answers have not really been related to what I needed so I am going to try explain my question in as much detail as I can and hopefully it will be easier for you to understand what I require.
I watched Bucky's slick game tutorials on youtube and made a 2D Java game, the game is basically a 2D player viewed from above (birds eye view) can move around a 2D map with user key input (up, down, left, right). The map the player moves around is very small so that meant boundaries had to be set so that the player could not walk off of the map, to give you a better idea of how this was done, here is the tutorial for setting up the voundries:
http://www.youtube.com/watch?v=FgGRHId8Fn8
The video will also show you exactly what the game is like.
The problem is, these boundaries only require one axis meaning that if the player is walking down you say something like "if player gets to the coordinate (number) on the X axis change the player movement to the opposite direction so that he can not go any further."
Now this creates a problem for me because this only requires one axis so it easy to set up and understand but if you look on the video, on the map there is a house and I want my player not to be able to walk over that also but this deals with 2 dimensions, I have looked at things like rectangle collisions and have seen things relating to them in the other posts but I get confused because I am new to Java and havent really done much with it at the moment apart from watching Bucky's tutorials.
My code at the moment for my game class has got the following methods: init, render and update. So to sum it up I really just want to set up a way of not letting my player walk through the house, I will mention also (I should have mentioned it in my other threads) as I am very new to Java, could you please take a step by step method of showing me how to set up the collisions, I mean even the basics of things like making the rectangle if required.
If my code is required please tell me and I will post it as soon as possible.
Thank you in advance.
You can set up the board as a 2x2 grid of a class that has has property such as 'isBlocked'. By default the edges of the board would have this property set to true to prevent the character from walking off the edge. When you add other obstacles such as a house or a wall the grid position(s) the object occupies would also have the property set to true. Then when moving a character you just check if the grid position the character moves to has the property set to false to see if it's an allowable move. This also makes it quite trivial to save the level data so you can just load them from disk later on.
Two possible options:
Extend Shape or Rectangle or the relevant Slick objects (they should exist IMO) and just check for intersect()
Look for (x1,y1) and (x2,y2) values such that it starts outside and ends up inside.
Assuming you have intersect() methods:
//Grab the previous position
prevPosX = movingobject.X;
prevPosY = movingobject.Y;
//Update the position
movingobject.update();
//Test for collision
if(movingobject.intersects(targetobj)) {
//If it collided, move it back
movingobject.X = prevPosX;
movingobject.Y = prevPosY;
//And reverse the direction
//(might want to do other stuff - e.g. just stop the object)
movingobject.speed *= -1; //Reverse the speed
}
in this case your update class should also add one more condition to look for the house. let say the cooridnates of house(assuming rectanglular house here for other shape just change x and y values) are (x1,y1)(x1,y2)(x2,y2)(x3,y1) you have to add a condition to make sure
x value is not between x1 and x2 and at the same time y value cannot between y1 and y2.

Design: an array of "enemy" objects for game AI

I made shoot em up like game.But I have only one ememy which fallows me on screen.But I want to make lots of enemys like each 10 second they will across on screen together 5 or 10 enemys.
ArrayList<Enemies> enemy = new ArrayList<Enemies>();
for (Enemies e : enemy) {
e.draw(g);
}
is it good creating array list and then showing on screen?
And Do I have to make some planing movements thoose enemies in my code ? I want that they vill appear not on same pozition.Like First 5 enemies will come top of screen then the other 5 or 10 enemies will come from left side.. so on.What is best solution for this?
And I have problem where to fullfiel this array like
enemy.add(new Enemies(750,60))
But this doesnt work ((
Use for example a random property and onScreen property. And set them when you show them on the screen.
Yes you can create an ArrayList for enemies, it's a common solution.
You can randomize the starting position ofthe enemies using the Random class. At the point where you create the enemy select Random coordinates for each.
You may want to have each enemy run in its own thread so that they move independent of each other too.

Categories