黑马程序员技术交流社区
标题:
新手写的一个贪食蛇,但问题解决不了了,求教!
[打印本页]
作者:
田建
时间:
2012-6-11 16:10
标题:
新手写的一个贪食蛇,但问题解决不了了,求教!
package game;
import javax .swing.*;
public class SnakeMain extends JFrame {
public SnakeMain(){
SnakeWindow win=new SnakeWindow();
add(win);
setTitle("贪食蛇:");
setSize(435,390);
setLocation(200,200);
setVisible(true);
}
public static void main(String[] args){
new SnakeMain();
}
}
复制代码
主要问题是下面这块:
package game;
import javax.swing.*;
import java.awt.*;//有几个比较好的布局
import java.awt.event.*;
import java.util.*;//里面有生成随机数的功能
import java.util.List;
public class SnakeWindow extends JPanel implements ActionListener,KeyListener,Runnable{
JButton newGame,stopGame;
int fenShu=0,speed=1;
Thread nThread;
boolean start=false;
Random r=new Random();
int rx=0,ry=0;
int temp=0,temp1=0,temp2=0;
JDialog dialog=new JDialog();
JLabel label=new JLabel("你输了,你的分数是:"+fenShu);
JButton ok=new JButton("好吧");
List<SnakeAct> list=new ArrayList<SnakeAct>();
public SnakeWindow(){
newGame=new JButton("开始");
stopGame=new JButton("退出");
this.setLayout(new FlowLayout(FlowLayout.LEFT));
newGame.addActionListener(this);
stopGame.addActionListener(this);
newGame.addKeyListener(this);
ok.addActionListener(this);
this.addKeyListener(this);
this.add(newGame);
this.add(stopGame);
dialog.setLayout(new FlowLayout());
dialog.add(label);
dialog.add(ok);
dialog.setSize(200,150);
dialog.setLocation(400,300);
dialog.setVisible(false);
}
public void paintComponent(Graphics g){
super.paintComponent(g);//这个方法先擦掉面板,再重新画
g.drawRect(10, 40, 400, 300);
g.drawString("分数:"+fenShu,150,20);
g.drawString("速度:"+speed,150,35);
g.setColor(new Color(0,255,0));
if(start){
g.fillRect(10+rx*10, 40+ry*10,10, 10);//绘制实心蛇块,大小是10*10,位置是从(10,40)开始,以10的进制往周围滚动!
g.setColor(new Color(255,0,0));
for(int i=0;i<list.size();i++)
{
g.fillRect(10+list.get(i).getX()*10,40+list.get(i).getY()*10, 10, 10);
}
}
}
public void keyTyped(KeyEvent e) {}
public void move(int x,int y){
if(minYes(x,y)){
list.get(0).setX(list.get(0).getX()+x);
list.get(0).setY(list.get(0).getY()+y);
eat();
otherMove();
repaint();
}else{
nThread=null;
label=new JLabel("你输了,你的分数是:"+fenShu);
dialog.setVisible(true);//设置死亡!
}
}
/* public void up(){
list.get(0).setY(list.get(0).getY()-1);
repaint();
}
//这里为了减少代码,可以定义一个move()方法,传入两个int型参数!
public void down(){
list.get(0).setY(list.get(0).getY()+1);
repaint();
}
public void left(){
list.get(0).setX(list.get(0).getX()-1);
repaint();
}
public void right(){
list.get(0).setX(list.get(0).getX()+1);
repaint();
}*/
public boolean minYes(int x,int y){
if(!maxYes(list.get(0).getX()+x,list.get(0).getY()+y)){
return false;
}
return true;
}
public boolean maxYes(int x,int y){
if(x<0||x>=40||y<0||y>=30){
return false;
}
for(int i=0;i<list.size();i++)
{
if(i>0&&list.get(0).getX()==list.get(i).getX()&&list.get(0).getY()==list.get(i).getY()){
return false;
}
}
return true;
}
public void keyPressed(KeyEvent e) {
if(start){
switch(e.getKeyCode()){
case KeyEvent.VK_UP:
move(0,-1);
temp=1;
break;
case KeyEvent.VK_DOWN:
move(0,1);
temp=2;
break;
case KeyEvent.VK_LEFT:
move(-1,0);
temp=3;
break;
case KeyEvent.VK_RIGHT:
move(1,0);
temp=4;
break;
default:
break;
}
}
}
public void run(){
while(start){
switch(temp){
case 1:
move(0,-1);
break;
case 2:
move(0,1);
break;
case 3:
move(-1,0);
break;
case 4:
move(1,0);
break;
default:
move(1,0);
break;
}
repaint();
fenShu+=100*speed;
try {
Thread.sleep(400-(50*speed));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void keyReleased(KeyEvent e) {}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==newGame){
newGame.setEnabled(false);
start=true;//按开始时将start设置为true
rx=r.nextInt(40);ry=r.nextInt(30);
SnakeAct tempAct=new SnakeAct();
tempAct.setX(20);
tempAct.setY(10);
list.add(tempAct);
requestFocus(true);
nThread=new Thread(this);
nThread.start();
repaint();
}
if(e.getSource()==stopGame){
System.exit(0);
}
if(e.getSource()==ok){
list.clear();
fenShu=0;
speed=1;
nThread = null;
start=false;
newGame.setEnabled(true);
dialog.setVisible(false);
repaint();
}
}
public void eat(){
if(rx==list.get(0).getX()&&ry==list.get(0).getY()){
rx=r.nextInt(40);ry=r.nextInt(30);
SnakeAct tempAct=new SnakeAct();
tempAct.setX(list.get(list.size()-1).getX());
tempAct.setY(list.get(list.size()-1).getY());
list.add(tempAct);
fenShu+=100+10*speed;
temp1+=1;
if((temp1-temp2)>=10){
temp1=temp2;
if(speed<=10){
speed+=1;
}
}
}
}
public void otherMove(){
for(int i=0;i<list.size();i++){
if(i==1){
list.get(i).setX(list.get(0).getX());
list.get(i).setY(list.get(0).getY());
}
else if(i>1){
SnakeAct tempAct = list.get(i-1);
list.set(i-1, list.get(i));
list.set(i, tempAct);
}
}
}
@SuppressWarnings("unused")
private int nextInt(){
return 0;
}
}
复制代码
package game;
public class SnakeAct {
private int x;
private int y;//这里两个私有变量,直接用source--Generate Getters and Setters 进行包装
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
复制代码
主要问题是1、吃到第一颗后会死掉,应该是判断的问题,没找到!
2、死了之后dialog上显示的分数仍为0!
求解,拜谢各位!
作者:
赵兵锋
时间:
2012-6-11 16:49
1.198,199行
tempAct.setX(list.get(list.size()-1).getX());
tempAct.setY(list.get(list.size()-1).getY());
这里将新添加的点的坐标设置为list中最后一个点的坐标,当此点添加到list中后,list中就存在两个坐标一模一样的点了。
97-102行:
在这部分的检测蛇是否自己吃自己时,若有两个点坐标一样,就判定蛇在吃自己了。
for(int i=0;i<list.size();i++)
{
if(i>0&&list.get(0).getX()==list.get(i).getX()&&list.get(0).getY()==list.get(i).getY()){
return false;
}
}
2.64行:
label=new JLabel("你输了,你的分数是:"+fenShu);这里将label指向了新对象,原对象里装的仍然是原始字符串
应该这样:label.setText("你输了,你的分数是:"+fenShu);
3.游戏结束后,线程应该结束掉
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2