I'm making a simple 2d shooter like space invaders, and I want to move my "enemy" only horizontally, from one side to another with the same speed.
How can I do that?
I have already did it for my "hero" with a KeyListener but I don't know how to do it automatically.
Here there's some code that might help.
public SimpleEnemy(String linkimg, int x, int y, int life) {
super(linkimg, x, y);
this.life=life;
this.isMoving=false;
}
public void move() {
x += dx;
y += dy;
}
What you need is a game loop. For example a while-loop that never ends (endless-loop) and which updates your hero position if needed.
while (true) {
// insert statement if move is needed here
move();
}
That's a pretty basic example but it should make things clear.
Since I assume that you are using java, you can take a look at some game frameworks like jgame. These frameworks take a similar approach and make it more comfortable to work with.
Edit:
Note that processors are running extremely fast these days and this endless-loop will be run very very often in a small amount of time (like 1000+ times per second). So you might have to limit the execution time of this loop, or your hero will be outside the screen faster you can look.
You can achive this with a sleep or something similar. Also these frameworks I mentioned will have this limitation on board.
Related
I'm making a platformer game. The jumping and movement are working, and now I want to program the collisions. I have a sort of idea as to how this will work:
I wasn't sure whether this question should be here or in the game dev site.
I have two Vector2's - velo and momentum (velo is the velocity). Both are (0, 0). The momentum is what's added to the velocity each frame.
Each frame, I first get the input. Momentum is increased and/or increased based on the keys pressed (e.g: if (Gdx.input.isKeyPressed(Keys.A)) { momentum.x -= speed; })
I then multiply the momentum by 0.15. This is so that it slows down.
After this, I multiply the velocity by 0.8.
Then, I add the momentum to the velocity, to increase the velocity, as
this is what actually moves the player.
I then add the velocity to the position of the player.
To apply the gravity, I add a gravity vector (0, -10) to the position of the player.
So I need to find a way to move the player, but not allowing it to overlap any part of the world. The world is made up of lots of Rectangle instances. The player's body is also an instance of Rectangle. Would it be easier to rewrite the collisions using Box2D? What I've tried is checking if the player overlaps any rectangles when it's moved, and if it will, not moving it. But this doesn't seem to take everything into account - sometimes it works, but other times, it stops before touching the world.
TL;DR: I want to make collisions of my player with a world which is stored as a grid of rectangles. How would I do this, as my player is also a Rectangle. Would it be easier to use Box2D?
This answer gives a good overview about the details of collision detection:
https://gamedev.stackexchange.com/a/26506
However, that might be a bit overwhelming if you just want to get a simple game going. Does your game loop happen in fixed interval or is it dependent on the framerate? Maybe you could solve a part of your issue by simply dividing the collision detection into more steps. Instead of moving the full way during one update, you could make 10 little updates that each move you only a 10th of the distance. Then you do a collision check after each step, so it's less likely that you stop too early or move through thin objects.
That would of course be more taxing on the performance, but it's a naive and easy to implement approach to a solution.
EDIT:
Just wrap the position update in a for loop. I don't know how your code for collision checking and updating, but the general structure would be something like
for (int i = 0; i < 10; i++) {
newPosX += deltaX * 0.1; // 1/10th of the usual update
newPosY += deltaY * 0.1; // 1/10th of the usual update
if (checkCollision(newPosX, newPosY))
{
posX = newPosX;
posY = newPosY;
}
else
{
break; // We hit something, no more mini-updates necessary.
}
}
So, I'm creating a isometric game in JAVA; to put it simply, it has a map made of tiles, and when the user drag the mouse on the screen, the map moves. To give you guys an idea, it currently looks like this:
Before the actual prototype version, I built a small java application that had no "Game Loop" per se; the only thing updating the tile-map position was the event listeners for the mouse dragging, and it called the repaint() method after the movement update. It worked fine, and I could select Tiles and move the map without a problem.
Since then, I rebuild the prototype thinking in developing something more like a real game engine, with a Game States Manager and a real Game Loop; the Game Loop code looks like this:
init();
long start;
long elapsed;
long wait;
while(running){
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if(wait < 0)wait = 5;
try{
Thread.sleep(wait);
} catch(Exception e) {
e.printStackTrace();
}
}
A GameStateManager is acessed with the update() and draw() methods, so I can draw the map just fine, like the older prototype. The problem happened when I dragged the mouse on the screen so the map could move; the animation became VERY croppy, in the extent that I could actually see the black background between the tiles moving before the final position of all tiles.
At first I thought the problem was in a concurrency between the Game Loop thread and the event listeners of the main class, because the mouseDragged event could be called while the JPanel was trying to draw what the map was like a moment ago; then I tested this on my game loop code:
SwingUtilities.invokeLater(new Runnable(){
public void run(){
draw();
drawToScreen();
}
});
//draw();
//drawToScreen();
And now the prototype is working just fine.
So, my question is, is this performance heavy, or just a bad practice in Java? Also, was my "concurrency" assumption right? This is my first time dealing with threads in Java, so I don't really know if I dealed with the problem the right way.
obs: This is the entire class I made in which the game loop is in:
http://pastebin.com/RMRHYc5X
obs2: If someone is interested, the game loop logic I worked in was based on a youtube java tutorial made by pj644 named "2D Game Programming in Java".
obs3: Sorry if the question became too big, this is my first time posting a question on this site!
Swing isn't really a great technology for writing games, it updates slowly and is quite limited in a number of ways.
Having said that yes calling invokeLater or using a SwingWorker would be the correct way to update the screen when your game thread has done its work.
Before you go too much further though I really suggest looking at a 2d or 3d java graphics and game framework. You will be able to get much better results that way and a lot of the work in terms of setting up the game loop, updates, managing frame rates, etc will be done for you.
I got some difficulties because i dont know how to code efficient.
I'm creating a vertical scrolling shooter & i wanna spawn a large number of enemies.
At certain y-coordinates of the map & give them a certain x coordinate.
If been doing testing this with a couple of enemies and in my Enemy-class the code i'm using now looks like this:
if (Background.bgY == -3972 && active == 0) {
active = 1;
type = 1;
centerX = enemyXstart4;
KnightmareGame.activated = 1;
KnightmareGame.activatedatY = Background.bgY;
}
Which basically looks for if the scrolled background is at coordinate Y, activate an enemy(bomb) of type 1 and give it starting coordinate centerX, activatedatY.
This means that for every single enemy im writing this block of code...
Then in my KnightmareGame Class (which holds the routine where the enemies get drawn on screen) i'm drawing every enemy manually, which looks osmething like this:
g.drawImage(currentBomb, bo1.getCenterX(), bo1.getCenterY(), this);
g.drawImage(currentBomb, bo2.getCenterX(), bo2.getCenterY(), this);
g.drawImage(currentBomb, bo3.getCenterX(), bo3.getCenterY(), this);
And in my collision detection method Im also checking every enemy 1 by 1:
if (projectileRect.intersects(KnightmareGame.bo1.bombRectangle)) {
visible = false;
if (KnightmareGame.bo1.health > 0) {
KnightmareGame.bo1.health -= 1;
}
if (KnightmareGame.bo1.health == 0) {
Enemy.animateFire= true;
etc., etc.
The problem is that the total amount of enemiess i exceeds 50, so if i would continue coding them 1 by 1 the code would get real messy.
What i was thinking of was that I might make an array list of all the y coordinates where i wanna spawn enemies with their subsequent x coordinate.
For example at -3900 i wanna spawn an enemy at x coordinate 200. At -3800 at x coordinate 300, etc. So an array list where every position holds 2 variables (x,y)
I just dont know (first of all) how to code for this array list.
And second. I have got no clue of how to automate my draw method like
g.drawImage(currentBomb, bo1.getCenterX(), bo1.getCenterY(), this);
I'm thinking of a loop, but dont know how the code...
Collision detection: here i also collision detect in ONE block of code for every enemy instead of compare every enemy in a single seperate block of code with my projectile.
Does any1 know how to do this? Or maybe if I should do it differently then what i'm thinking of right now?
Help will be very much appreciated!
Handling multiple enemies
Create an ArrayList<Enemy> enemies;
Then use
for (Enemy bo : enemies) {
// logic for each enemy.
}
Don't forget to remove old enemies after destroying or going out of screen.
Don't keep creating new objects every time. Use a object pool for efficiency.
Improving collision efficiency
For large number of entities to be checked for collision, generally a broadphase algorithm is used.
See if it is required in your case.
You might also try some spatial optimizations like quad-trees.
These might just be wiki links, but I suppose you can search further if you know what to search for.
Hope this helps.
Good luck.
This is an assignment, so I'd prefer an explanation more than straight code.
The task is to draw circles recursively like the picture
I can't work out the pattern to draw it though. A turtle class is used to draw the circles.
This is what I've managed so far
private void draw(int level, double size){
if(level < 0) return;
turtle.setPenDown(true);
turtle.drawOval(size);
//Here I think there needs to be code to move to the positions of the other circles?
draw(level-1,size/2);
}
But of course it only draws this at the moment:
EDIT:
Maybe some code could help, this isn't going to well for me.
If it's got to be recursive then I would suggest something like the following, I'll just talk algorithm wise since you asked to not have code come back.
If we're going to think of this as a long series of self-similar circles then the general process is pretty straightforward.
Check if there are n circles in your current row. The row is defined as whatever direction is forward/backward for your turtle. If you want you could store the circles drawn in a 2-d list or array to make checking easier.
If there are n circles, then turn right, otherwise draw a circle and move forward.
That will draw the circles from the outside in. If you want it from the inside out it probably makes less sense to do recursion but it would be something like this:
Function: Draw circle. Turn right if you can, otherwise move forward.
Stop when the total number of circles is equal to n^2
Hope that helps.
I'm in the process of developing a 2-D game for android which primarily i'm using as an experience to learn the in's and out's of programming for android apps, so naturally i run into a lot of puzzles to work through. Currently, my main activity instantiates a custom class which extends SurfaceView and implements SurfaceHolder.Callback. This view instantiates a thread which handles most of the logic and all the graphics processing (this includes instantiating a canvas and drawing to it., etc.
Well, being that I am a beginner I wasn't thinking when I started that designing the canvas to be much larger than the screen and to allow users to scroll around to see all parts of the canvas... but alas, that's what I need to happen.
If there is an easy way to do this, please let me know.
My best guess is putting the actual creation of the canvas in a separate class which extends ScrollView and somehow just calling all the Draw()'s to that canvas from my thread. is this possible? my click events are actually captured from the main activity (just fyi).
The best option would be to use a Camera to translate the canvas. Do something like this:
// Creates a new camera object
Camera mCam = new Camera();
float startX;
float startY;
#Override
public void onTouch(MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
startX = event.getX();
startY = event.getY();
}
else if(event.getAction() == MotionEvent.ACTION_MOVE)
{
float x = event.getX();
float y = event.getY();
// Lets you translate the camera by the difference
mCam.translate(x -startX, startY - y, 0.f);
startX = event.getX();
startY = event.getY();
}
}
#Override
public void onDraw(Canvas canvas)
{
// Draw here the objects you want static in the background
canvas.drawBitmap(mBackground, 0, 0, null);
canvas.save();
mCam.applyToCanvas();
// Draw here the objects you want to move
canvas.drawBitmap(mBall, 0, 0, null);
canvas.restore();
// Draw here the objects you want static on the forebround
canvas.drawBitmap(mScore, 0, 0, null);
}
Notice that you are drawing mBall at 0,0 but due to the camera translation it will move by the amount specified. I hope this helps. Have fun :)
I slept on the problem and came up with (if i don't say so myself) A brilliant, relatively simple and elegant solution. Sorry to toot my own horn but I was literally ecstatic that i was able to come up with this.
If anyone is thinking of using this method there are a couple of conditions that made this a good choice. First, all of my objects are drawables with predefined locations using the setBounds(int,int,int,int) method, all objects also store their own coordinates for the location to draw on the canvas and all objects are called in hashmaps which allows me to call and process all the objects in existence.
Now I was thinking about what kabuko said and how it's such a waste to draw a huge canvas and how id run into click event problems, that's when I came up with this.
when a screen touch event occurs near the edge of the screen, a custom method Scroll() is called which loops through every object and adjusts the stored coordinates of the object location depending on which direction the user is trying to scroll. after it increments the objects location, it (in parallel) increments a pair of variables for x and y offset. This offset is then factored into the coordinates of the touch events so that objects can still be selected by touch regardless of the position the screen is scrolled to.
then for performance's sake a simple if statement makes it so that draw is only called on an object if that objects coordinates fall in the range of the screen.
Sorry to gloat but I really surprised and impressed myself with this, haha. I've really only been coding about a month and I almost have a fully functional 2D strategy game!
Java for dummies paid off, lol.
You could give your approach a try, even though it's not really a strategy I'd ever use myself. I suspect you're going to run into some issues with that approach anyway though. If your game already uses touch for input, you're going to have conflicts. Also, if performance is at all a concern (especially if you have any animation), you don't want go with this approach.
If you're going as far as dealing with threading, performance probably matters. Drawing is expensive, and if you make a huge canvas, you'll have to be rendering the whole thing and it will cost you. You should only draw what's on the screen (more or less). Sorry, but you'll probably need a "major overhaul"...
That said, it's really not that bad to deal with scrolling. You probably have coordinates for everything you're drawing. All you need to do is keep track of your "current coordinates" and then translate your drawing x and y by your current x and y. Dealing with the performance stuff, there's a lot you can do, but that's starting to get a bit off-topic. Take a look at these videos if you want to know more:
http://www.youtube.com/watch?v=U4Bk5rmIpic
http://www.youtube.com/watch?v=7-62tRHLcHk
The simple trick with side-scrolling games is to divide your world into tiles, where each tile has a specified amount of area.
Displaying a Tile Based Map
Scrolling a Tile Based Map