前言
玩儿了这么多年的游戏,您有想过自己动手来写一个么,哈哈哈不废话啦,学完Java一快有一年了,总结了n多次,这次利用周末假期时间刷了一些视频,自己写了一个贪吃蛇小游戏,下面我们来看看他是怎么实现的吧!
游戏图片
主要实现代码
界面坐标
这个就是相当于把整个窗体变成网格形式,蛇????通过一格一格的移动,进而实现动起来
package com.zzk.snake.core;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
public abstract class SnakeObject implements Drawable {
int x;//横坐标
int y;//纵坐标
Image img;//图片
int width;//图片宽度
int height;//图片高度
public boolean live;//死亡/存活/叛断是否存活
@Override
public abstract void draw(Graphics g);
/**
* 获取图片对应的矩形 把图片变成矩形,即为游戏战场
*
* @return
*/
public Rectangle getRectangle() {
return new Rectangle(x, y, width, height);
}
}
定义窗体界面
其实游戏最主要的就是不停的变换,一帧一帧的让他动起来,实现界面刷新,大家看一下上面代码,应该不难理解!
public class MyFrame extends Frame{
/**
* 加载窗体
*/
public void loadFrame(){
this.setTitle("贪吃蛇");//设置窗体标题
this.setSize(Constant.GAME_WIDTH, Constant.GAME_HEIGHT);//设置窗体大小
this.setBackground(Color.red);//设置背景
this.setLocationRelativeTo(null);//居中
//设置可关闭
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//设置可见
this.setVisible(true);
//运行重绘线程
new MyThread().start();
}
/**
* 防止图片闪烁,使用双重缓存
*
* @param g
*/
Image backImg = null;
@Override
public void update(Graphics g) {
if (backImg == null) {
backImg = createImage(Constant.GAME_WIDTH, Constant.GAME_HEIGHT);
}
Graphics backg = backImg.getGraphics();
Color c = backg.getColor();
backg.setColor(Color.BLACK);
backg.fillRect(0, 0, Constant.GAME_WIDTH, Constant.GAME_HEIGHT);
backg.setColor(c);
paint(backg);
g.drawImage(backImg, 0, 0, null);
}
/**
* 这里创建一个不断重绘的线程内部类
*
* @param
*/
class MyThread extends Thread{
@Override
public void run() {
while(true){
repaint();
try {
sleep(30);//每30毫秒重绘一次
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
食物类
定义一个贪吃蛇的食物这里是一个草莓????作为被吃食物,草莓被吃之后分数增加,蛇身长度+1
package com.zzk.snake.core;
import java.awt.Graphics;
import java.awt.Point;
import com.zzk.snake.constant.Constant;
import com.zzk.snake.util.ImageUtil;
public class Food extends SnakeObject{
public Food(){
this.live=true;
this.img=ImageUtil.images.get("food");
this.width=img.getWidth(null);
this.height=img.getHeight(null);
this.x=(int) (Math.random()*(Constant.GAME_WIDTH-width+10));
this.y=(int) (Math.random()*(Constant.GAME_HEIGHT-40-height)+40);
}
/**
* 食物被吃的方法
* @param mySnake
*/
public void eaten(MySnake mySnake){
if(mySnake.getRectangle().intersects(this.getRectangle())&&live&&mySnake.live){
this.live=false;//食物死亡
mySnake.setLength(mySnake.getLength()+1);//长度加一
mySnake.score+=100*mySnake.getLength();//加分
}
}
/**
* 绘制食物
*/
@Override
public void draw(Graphics g) {
g.drawImage(img, x, y, null);
}
}
游戏中的骚操作
让我们来看看游戏中有哪些骚操作吧!让你更好的体验这个游戏的乐趣!
撞界面
private void outOfBounds() {
boolean xOut = (x <= 0 || x >= (Constant.GAME_WIDTH- width));
boolean yOut = (y <= 40 || y >= (Constant.GAME_HEIGHT - height));
if (xOut || yOut) {
live = false;
}
将这里的false改成true这样子即使你撞到界面也不会死亡,是不是很爽呢,地图所向无敌,横冲直撞!
撞蛇身
/**
* 处理是否吃到到身体问题
*/
public void eatBody(){
for (Point point : bodyPoints) {
for (Point point2 : bodyPoints) {
if(point.equals(point2)&&point!=point2){
this.live=false;//食物死亡
}
将这里的false改成true之后,在后期你的长度可能很长,这样子,自己从自己身上绕过去也没事儿,不会出现游戏结束字样。
界面大小
private void outOfBounds() { boolean xOut = (x <= 0 || x >= (Constant.GAME_WIDTH- width)); boolean yOut = (y <= 40 || y >= (Constant.GAME_HEIGHT - height)); if (xOut || yOut) { live = false;
将这里的false改成true之后,整个界面你就可以畅通无阻了,甚至可以跑到界面外面去,哈哈哈。
长度和加分
/** * 食物被吃的方法 * @param mySnake */ public void eaten(MySnake mySnake){ if(mySnake.getRectangle().intersects(this.getRectangle())&&live&&mySnake.live){ this.live=false;//食物死亡 mySnake.setLength(mySnake.getLength()+1);//长度加一 mySnake.score+=100*mySnake.getLength();//加分
我写的时候,默认长度是+1,那么你想一下加入改成10或者100 ,界面是什么感觉,哈哈哈,最重要的是分数,这里是100,同理你也可以改成呢心中那个随意的数字。
总结
自己写游戏,你不仅知识得到了总结,而且最重要的就是你自己玩儿起来,感觉就会不一样,还有就是你可以改成你自己想要的样子,在这里不受金钱和外物的影响,这里只属于你的王国,大家也可以动手写起来哟!然后说明一下,可能这几天不能一天一更了,期末了,我也得好好复习了!