版权声明:您好,欢迎来到我的技术博客。 https://blog.csdn.net/zwyjg/article/details/8688653
自己修改别人的程序,
本来是一个全屏游戏,我把它改正窗口的,不过只有部分功能
全屏代码http://download.csdn.net/download/zwyjg/9914576
Hufan.java
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Vector;
public class Hufan extends JFrame implements Runnable{
HuPanel hp;
Manager manager;
public static void main(String[] args) {
// TODO Auto-generated method stub
new Hufan();
}
public Hufan(){
manager=new Manager();
hp=new HuPanel();
new Thread(this).start();
new Thread(hp).start();
this.add(hp);
this.addKeyListener(hp);
this.setTitle("Java超级玛丽");
this.setSize(800, 700);
this.setLocation(500, 200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
hp.repaint();
manager.updateCreature(hp.player, 25);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class HuPanel extends JPanel implements KeyListener,Runnable{
BufferedImage bground,playerImg;
Player player;//玛丽对象
float offsetX;
float offsetY;
int mapWidth = Manager.newMap.getWidth()*64;//地图的宽度
GameAction[] keyActions = new GameAction[600];//按键数组
GameAction moveLeft;//左移动按键
GameAction moveRight;//右移动按键
GameAction jump;//跳跃
public HuPanel(){
player = new Player();
moveLeft = new GameAction("moveLeft");
moveRight = new GameAction("moveRight");
jump = new GameAction("jump");
keyActions[KeyEvent.VK_LEFT] = moveLeft;
keyActions[KeyEvent.VK_RIGHT] = moveRight;
keyActions[KeyEvent.VK_SPACE] = jump;
try {
bground=ImageIO.read(new File("background.png"));
playerImg=ImageIO.read(new File("player1.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void paint(Graphics g){
super.paint(g);
//画界面时,都是相对坐标,
offsetX = 400 -player.x-64;//JFrame宽度的一半减去玛丽的坐标,再减去玛丽自己的宽度。
offsetX = Math.min(offsetX, 0);//返回两个 double 值中较小的一个。
offsetX = Math.max(offsetX, 800 -mapWidth);//返回两个 double 值中较大的一个。
offsetY = 600 -Manager.newMap.getHeight()*64;
//画背景
if (bground != null) {
float x = offsetX * (800 - 1600)/ (800 - mapWidth);
g.drawImage(bground, (int)x, 0, null);
}
//画地板砖
int firstTileX =(int)-offsetX/64;
int lastTileX = (int)firstTileX +800/64 + 1;
for (int y=0; y<Manager.newMap.getHeight(); y++) {
for (int x=firstTileX; x <= lastTileX; x++) {
Image image = Manager.newMap.getTile(x, y);
if (image != null) {
g.drawImage(image,x*64 + (int)offsetX,y*64 + (int)offsetY,null);
}
}
}
// 画玛丽
g.drawImage(playerImg,(int)player.x + (int)offsetX, (int)player.y + (int)offsetY,null);
}
private GameAction getKeyAction(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode < keyActions.length) {
return keyActions[keyCode];
}else {
return null;
}
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
//从keyActions数组得到按键对象
GameAction gameAction = this.getKeyAction(e);
if (gameAction != null) {
gameAction.press();
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
GameAction gameAction = getKeyAction(e);
if (gameAction != null) {
gameAction.release();
}
}
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void run() {//检测哪些键被按下
// TODO Auto-generated method stub
while(true){
float velocityX = 0;
if (moveLeft.isPressed()) {
velocityX-=0.5f;
}
if (moveRight.isPressed()) {
velocityX+=0.5f;
}
if (jump.isPressed()) {
player.jump(false);
}
player.dx=velocityX;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
GameAction.java
/**
* 按键类
* @author Administrator
*
*/
public class GameAction {
public static final int NORMAL = 0;//正常的
int DETECT_INITAL_PRESS_ONLY = 1;//检测初步按
int RELEASED = 0;//释放
int PRESSED = 1;//按下
int WAITING_FOR_RELEASE = 2;//等待释放
String name;
int behavior;//行为;态度;(机器等的)运转状态;(事物的)反应
int amount;//按键次数量
int state;
public GameAction(String name) {
this.name=name;
}
public synchronized void press() {
press(1);
}
public synchronized void press(int amount) {
if (state != WAITING_FOR_RELEASE) {
this.amount+=amount;
state = PRESSED;
}
}
public synchronized boolean isPressed() {
return (getAmount() != 0);
}
public synchronized void release() {
state = RELEASED;
}
public synchronized int getAmount() {
int retVal = amount;
if (retVal != 0) {
if (state == RELEASED) {
amount = 0;
}
// else if (behavior == DETECT_INITAL_PRESS_ONLY) {
// state = WAITING_FOR_RELEASE;
// amount = 0;
// }
}
return retVal;
}
}
Manager.java
import java.awt.*;
import java.io.*;
import java.util.*;
import javax.swing.ImageIcon;
/**
* 管理类
* @author Administrator
*
*/
public class Manager{
ArrayList tiles;//地板砖图像的集合
ArrayList lines;//地图的每行数据
int width = 0;//地图的宽
int height = 0;//地图的高
BufferedReader reader;//缓存地图文本
static float GRAVITY = 0.0015f;//重力
Point pointCache = new Point();
static TileMap newMap;//地图对象
public Manager(){
lines = new ArrayList();
tiles = new ArrayList();
//读取地图
try {
reader = new BufferedReader(new FileReader("map1.txt"));
while(true){
String line = reader.readLine();//读取一行
if (line == null) {//如果读取的一行为空
reader.close();
break;
}
lines.add(line);
//主要是为了读取最下面一行的个数,也就是地图和宽度
width = Math.max(width, line.length());// 取两者最大的数
}
//读取地板砖图片到内存
char cha = 'A';
while (true) {
String name = "tile_" + cha + ".png";
File file = new File(name);
if (!file.exists()) {//读取的文件不存在,就退出循环
break;
}
tiles.add(loadImage(name));//将图片加到集合
cha++;
}
height = lines.size();
newMap = new TileMap(width, height);
//设置地图中。每个位置的数据
for (int y=0; y<height; y++) {//循环每一列
String line = (String)lines.get(y);
for (int x=0; x<line.length(); x++) {//循环每一行
char ch = line.charAt(x);//返回指定索引处的 char 值。
//检查字符是否有效
int tile = ch - 'A';
//得到的字母是否大于A,并且小于地板图片的个数 时,说明字符有效
if (tile >= 0 && tile < tiles.size()) {
newMap.setTile(x, y, (Image)tiles.get(tile));
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Image loadImage(String name) {
String filename = name;
return new ImageIcon(filename).getImage();
}
public void updateCreature(Player player,long elapsedTime)
{
player.dy=player.dy+GRAVITY * elapsedTime;
// change x 改变×
float dx = player.dx;//x速度
float oldX = player.x;//x坐标
float newX = oldX + dx * elapsedTime;//
Point tile =getTileCollision(player, newX, player.y);
if (tile == null) {
player.x=newX;
}else {
// line up with the tile boundary线与瓦片边界
// if (dx > 0) {
// player.setX(tile.x/64-80);
// }else if (dx < 0) {
// player.setX((tile.x + 1)64);
// }
player.collideHorizontal();
}
// change y
float dy = player.dy;
float oldY = player.y;
float newY = oldY + dy * elapsedTime;
tile = getTileCollision(player, player.x, newY);
if (tile == null) {
player.y=newY;
}else {
// line up with the tile boundary
//线与瓦片边界
// if (player.dy > 0) {
// player.setY(tile.y/64-64);
// }
// else if (player.dy < 0) {
// player.setY((tile.y + 1)/64);
// }
player.collideVertical();
}
}
//获取瓷砖碰撞
public Point getTileCollision(Player sprite,float newX, float newY)
{
float fromX = Math.min(sprite.x, newX);
float fromY = Math.min(sprite.y, newY);
float toX = Math.max(sprite.x, newX);
float toY = Math.max(sprite.y, newY);
// get the tile locations
//获取瓷砖的位置
int fromTileX = (int)fromX/64;
int fromTileY =(int)fromY/64;
int toTileX =(int)(toX + 80 - 1)/64;
int toTileY =(int)(toY + 64 - 1)/64;
// check each tile for a collision
//检查每个瓷砖的碰撞
for (int x=fromTileX; x<=toTileX; x++) {
for (int y=fromTileY; y<=toTileY; y++) {
if (x < 0 || x >= newMap.getWidth() ||newMap.getTile(x, y) != null){
// collision found, return the tile
//碰撞发现,返回瓦
pointCache.setLocation(x, y);
return pointCache;
}
}
}
// no collision found
//发现无碰撞
return null;
}
}
Player.java
/**
* 玛丽类
*/
import java.awt.Point;
public class Player{
float x;//玛丽的X坐标
float y;
float dx;//玛丽的X速度
float dy;
float JUMP_SPEED = -.95f;//跳跃速度
boolean onGround;//在地面上
float GRAVITY = 0.002f;//重力
public Player(){
}
//碰撞横
public void collideHorizontal() {
dx=0;
}
//垂直碰撞
public void collideVertical() {
// check if collided with ground
//检查如果撞到地面
if (dy > 0) {
onGround = true;
}
dy=0;//设置Y速度为0
}
public void jump(boolean forceJump) {
if (onGround || forceJump) {
onGround = false;//false为不在地面上
dy=JUMP_SPEED;
}
}
}
TileMap.java
/**
* 地板砖地图类
*/
import java.awt.Image;
import java.util.*;
public class TileMap {
Image[][] tiles;//图片数组
public TileMap(int width, int height) {
tiles = new Image[width][height];
}
public void setTile(int x, int y, Image tile) {
tiles[x][y] = tile;
}
public Image getTile(int x, int y) {
if (x < 0 || x >= getWidth() ||y < 0 || y >= getHeight()){
return null;
}else {
return tiles[x][y];
}
}
public int getWidth() {
return tiles.length;
}
public int getHeight() {
return tiles[0].length;
}
}
map1.txt
IIIIIII IIIIIII
EF
EF EGD
EF CD EGAD
BBBBBBBBGHBBBBBBBGHBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBGAAHBBBBBBBBBBB
background.png
扫描二维码关注公众号,回复:
3456154 查看本文章
player1.png
tile_A.png
tile_B.png
tile_C.png
tile_D.png
tile_E.png
tile_F.png
tile_G.png
tile_H.png
tile_I.png