swing - Smooth animation in a snake game (java)? -
swing - Smooth animation in a snake game (java)? -
i have made basic snake game in java , need help getting smoother animation. each segment of snake 20x20 square, made snake move @ step of 20 pixels per tick. makes snake move seemingly on grid, means line nutrient spawns on "grid". problem is, when seek , move step of 3, not aligned "grid" anymore. more serious problem have snake moves moving first square, settings of others next position in array (see code). problem is, when moves step of 3, snake shrink there gap of 3 between each origin, instead of 20. can help these problems? can add together entire source code if needed.
import java.awt.*; import java.awt.event.*; import java.awt.image.bufferstrategy; import java.io.bufferedreader; import java.io.bufferedwriter; import java.io.filereader; import java.io.filewriter; import java.io.ioexception; import java.util.random; import javax.swing.timer; public class player1 extends canvas implements runnable { private keyevents keyevent; private element [] elements; private element goal; private int numsegments, score, endy, quitx, snakesize, windowsize; private font scorefont; private long cycletime; private final int frame_delay; private bufferstrategy bf; private boolean gameover, isrunning; public player1(frame window) { setsize(new dimension(window.getwidth(), window.getheight())); frame_delay = 20; windowsize = 400; snakesize = 20; score = 0; isrunning = false; numsegments = 5; scorefont = new font("verdana", font.bold, snakesize); elements = new element [300]; goal = new element(randompos(snakesize,windowsize-snakesize),randompos(snakesize,windowsize-snakesize), snakesize, color.green); keyevent = new keyevents(); keyevent.setp1keys(2,true); (int i=0, xpos = round(windowsize/2), ypos = round(windowsize/2); i<numsegments; i++, xpos+=snakesize) { elements[i] = new element(xpos,ypos, snakesize, color.blue); } addkeylistener(new keyadapter() { public void keypressed(keyevent evt) { keyevent.moveit(evt); switch(evt.getkeycode()){ case keyevent.vk_escape: isrunning = false; screen.newmenu(); } } }); } public void start(player1 ex){ isrunning = true; thread gamethread = new thread(ex); gamethread.setpriority(thread.min_priority); gamethread.start(); } public void run(){ cycletime = system.currenttimemillis(); while(isrunning){ logic(); render(); sync(); } } public void render() { if (bf==null){ bf = getbufferstrategy(); } graphics2d g2 = null; try{ g2 = (graphics2d) bf.getdrawgraphics(); g2.setcolor(color.black); g2.fillrect(0, 0, windowsize, windowsize); (int i=0;i<numsegments;i+=1) { elements[i].draw(g2); } g2.setcolor(color.green); goal.draw(g2); g2.setcolor(color.orange); g2.fill3drect(0, 0, windowsize, snakesize, true); g2.setcolor(color.red); g2.setfont(scorefont); g2.drawstring("score: "+score, 5, snakesize-4); fontmetrics fm = g2.getfontmetrics(); g2.setcolor(color.blue); fm = g2.getfontmetrics(); g2.setcolor(color.black); quitx = (windowsize - fm.stringwidth("esc = quit")-5); g2.drawstring("esc = quit",quitx,snakesize-snakesize/5); }finally{ g2.dispose(); } bf.show(); toolkit.getdefaulttoolkit().sync(); } public void sync(){ cycletime = cycletime + frame_delay; long difference = cycletime - system.currenttimemillis(); seek { thread.sleep(math.max(0, difference)); } catch(interruptedexception e) { e.printstacktrace(); } } public void logic(){ int x = elements[0].getx(); int y = elements[0].gety(); rectangle elementrect = elements[0].getrect(); keyevent.setp1pressed(false); //movement for(int = numsegments-1; i>0; i--){ elements[i].setx(elements[i-1].getx()); elements[i].sety(elements[i-1].gety()); } if(keyevent.getp1keys(0)){ elements[0].sety(y+20); } else if(keyevent.getp1keys(1)){ elements[0].sety(y-20); } else if(keyevent.getp1keys(2)){ elements[0].setx(x-20); } else if(keyevent.getp1keys(3)){ elements[0].setx(x+20); } if(elements[0].getx()>windowsize-snakesize){ elements[0].setx(0); } else if(elements[0].getx()<0){ elements[0].setx(windowsize-snakesize); } if(elements[0].gety()>windowsize-snakesize){ elements[0].sety(0); } else if(elements[0].gety()<0+snakesize){ elements[0].sety(windowsize-snakesize); } for(int i=0; i<numsegments; i++){ elements[i].updaterect(); } //collision if(elementrect.intersects(goal.getrect())){ numsegments+=1; elements[numsegments-1] = new element(elements[numsegments-2].getx(),elements[numsegments-2].gety(), snakesize,color.blue); goal.setx(randompos(snakesize,windowsize-snakesize)); goal.sety(randompos(snakesize,windowsize-snakesize)); score+=1; } for(int i=1; i<numsegments; i++){ if(elementrect.intersects(elements[i].getrect())){ gameover(); } } } public void gameover(){ isrunning = false; } public int randompos(int min,int max){ system.out.println(snakesize); int range = max-min; random randompos = new random(); int pos = randompos.nextint(range)+min; pos*=2; pos += snakesize; pos /= snakesize*2; pos *= snakesize*2; pos/=2; homecoming pos; } }
1) utilize java naming conventions correctly player1
should player1
etc
2) don't utilize pre_historic awt canvas
, utilize swing jpanel, jlabel or jcomponent
, same frame ---> jframe
3) don't utilize keylistener
, because required focus
canvas, easiest utilize keybinding
4) have issues concurency in swing, utilize javax.swing.timer rather wrong implemntations runnable#tread
5) never utilize thread.sleep(math.max(0, difference));
awt/swing j/components, because block eventdispatchtread, , wrong implentations thread.sleep() yoour gui freeze os remain un_responsible, utilize javax.swing.timer dealying event in swing
6) post here sscce demonstrating real uissues, instead of bunch of un_relatted code , somw anothere missed (maybe yes, maybe not) of import classes,
java swing animation
Comments
Post a Comment