⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mazecanvas.java

📁 J2ME 3D 第一人称射击迷宫类手机游戏源码。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
					wallTextureImage));
			wallTexture
					.setWrapping(Texture2D.WRAP_REPEAT, Texture2D.WRAP_CLAMP);
			wallTexture.setBlending(Texture2D.FUNC_REPLACE);
			wallTexture.setFiltering(Texture2D.FILTER_LINEAR,
					Texture2D.FILTER_NEAREST);
			wallAppearance.setTexture(0, wallTexture);// 将墙壁纹理添加到墙壁的外观属性中
			wallClearAppearance.setTexture(0, wallTexture);// 将墙壁纹理添加到半透明外观属性中
		}

		Enumeration wallsEnum = maze.createPlanes();// 调用maze类的createPlanes创建所有Plane对象
		while (wallsEnum.hasMoreElements()) {// 遍历所有的Plane对象
			Mesh wallMesh = ((Plane) wallsEnum.nextElement()).createMesh();// 用Plane对象创建Mesh平面
			wallMesh.setAppearance(0, wallAppearance);// 将墙壁设置为基本外观
			world.addChild(wallMesh);// 将墙壁添加到游戏场景中
		}

	}

	// decides whether it is allowed to move to a given place
	// otherwise it is possible to cross walls and go outside the maze
	private boolean canMove(float stepx, float stepz, boolean forward) {
		float x = locationx + stepx;
		float z = locationz + stepz;
		// First check if inside the maze area
		float mazeSize = MAZE_SIDE_LENGTH / 2 - 2;
		if (x <= -mazeSize || z <= -mazeSize || x > mazeSize || z > mazeSize) {
			return false;
		}
		// collision with walls is easily implemented using picking
		// if there is something in front of the camera and the distance is too
		// small, the movement is not allowed
		RayIntersection ri = new RayIntersection();
		// inverse the point of view to detect if it is moving
		// bacwards
		if (!forward) {
			normalCamera.postRotate(180, 0f, 1f, 0f);
		}
		if (world.pick(-1, 0.5f, 0.5f, normalCamera, ri)) {
			Node selected = ri.getIntersected();
			if (selected instanceof Mesh) {
				// multiply per 9 since that's the size of a step
				float distance = ri.getDistance() * 9;

				if (distance <= 0.1) {
					return false;
				}
			}
		}
		if (!forward) {
			// revert to the original view
			normalCamera.postRotate(-180, 0f, 1f, 0f);
		}
		return true;
	}

	private static boolean moved = false;

	// the method checks whenever the keys are pressed
	private void checkKeys() {
		int keyState = getKeyStates();
		moved = false;

		// 如果按下Fire键,则将拾取到的Mesh对象设为半透明外观
		if ((keyState & FIRE_PRESSED) != 0) {
			seeThrough();
		}
		// here we assume only one button is pressed otherwise the "second"
		// press is ignored
		if ((keyState & LEFT_PRESSED) != 0) {
			turnLeft();
		} else if ((keyState & RIGHT_PRESSED) != 0) {
			turnRight();
		} else if ((keyState & UP_PRESSED) != 0) {
			moveForward();
		} else if ((keyState & DOWN_PRESSED) != 0) {
			moveBack();
		} 

		// if moved we make the last transparent wall normal
		// and reset the view
		if (moved) {
			if (!finished && maze.isAtTheEnd(locationx, locationz, 4f)) {
				finished = true;
			}
			// if there was a mesh semi transparent
			// return to normal
			if (transparentMesh != null) {
				transparentMesh.setAppearance(0, wallAppearance);
				transparentMesh.setAlphaFactor(1f);
				transparentMesh = null;
			}
			// if we move we reset the top view state
			if (topView) {
				switchView();
			}
			setupCamera();
		}

	}

	protected void seeThrough() {
		RayIntersection ri = new RayIntersection();// 创建一个拾取光束
		if (world.pick(-1, 0.5f, 0.5f, normalCamera, ri)) {// 用该光束对场景拾取Mesh对象
			Node selected = ri.getIntersected();// 获取光束所拾取到的内容
			if (selected instanceof Mesh) {// 如果拾取到的是Mesh对象(前面已经将开始结束标志设为不可拾取)
				transparentMesh = ((Mesh) selected);
				transparentMesh.setAppearance(0, wallClearAppearance);// 将该墙壁设置为半透明外观属性
				transparentMesh.setAlphaFactor(0.8f);// 透明alpha因子为0.8
			}
		}
	}

	protected void moveForward() {
		// move forward, but first check if it is allowed
		if (canMove(-stepx, -stepz, true)) {
			locationx -= stepx;
			locationz -= stepz;
		}
		moved = true;
	}

	protected void moveBack() {
		// move backwards, but first check if it is allowed
		if (canMove(stepx, stepz, false)) {
			locationx += stepx;
			locationz += stepz;
		}
		moved = true;
	}

	protected void turnLeft() {
		// 当游戏左键被按下
		angley += ANGLE_STEP; // 当前角度增加旋转角度
		stepx = STEP * (float) Math.sin(Math.toRadians(angley)); // 计算x方向的偏移量
		stepz = STEP * (float) Math.cos(Math.toRadians(angley)); // 计算z方向的偏移量
		// 设置背景的裁剪区域向右偏移一点
		background.setCrop(background.getCropX() + 3, 0, getWidth(),
				getHeight());
		flagX1 = flagX1 + (int) stepx;
		flagY1 = flagY1 + (int) stepz;
		flagX2 = flagX2 - (int) stepx;
		flagY2 = flagY2 - (int) stepz;
		moved = true; // 已经成功移动
		System.out.println("stepx=" + stepx);
		System.out.println("stepz=" + stepz);
	}

	protected void turnRight() {
		// 当游戏右键被按下
		angley -= ANGLE_STEP;
		stepx = STEP * (float) Math.sin(Math.toRadians(angley));
		stepz = STEP * (float) Math.cos(Math.toRadians(angley));
		// 设置背景的裁剪区域向左偏移一点
		background.setCrop(background.getCropX() - 3, 0, getWidth(),
				getHeight());
		flagX1 = flagX1 + (int) stepx;
		flagY1 = flagY1 + (int) stepz;
		flagX2 = flagX2 - (int) stepx;
		flagY2 = flagY2 - (int) stepz;
		moved = true; // 已经成功移动
		System.out.println("stepx=" + stepx);
		System.out.println("stepz=" + stepz);
	}

	// key pressed used to show the main menu
	protected void keyPressed(int keyCode) {
		if (keyCode < 0) {
			// MyGame.showMenu();
			if (MyGame.isShowingPopup()) {
				MyGame.getCurrentPopup().dispose();
			}
			MyGame.exitGame();
		}
		if (keyCode == KEY_POUND) {
			switchView();
		}
		if (keyCode == KEY_STAR) {
			switchWeapon();
		}
		if (keyCode == KEY_NUM0) {
			seeThrough();
		}
	}

	public static int weapon_index = 0;

	private void switchWeapon() {
		// 换武器
		if (weapon_index >= weapons.length)
			weapon_index = 0;
		mainWeapon = weapons[weapon_index++];
	}

	private void reloading() {
		// 换弹夹
	}
	// 设置摄像机位置
	private void setupCamera() {
		normalCamera.setOrientation(angley, 0f, 1f, 0f);
		normalCamera.setTranslation(locationx, 10f, locationz);
	}

	// 绘制指南针
	// 初始化指南针的坐标
	final int X1 = getWidth() - 22, X2 = getWidth() - 22, Y1 = 39, Y2 = 14;

	int flagX1 = X1, flagY1 = Y1, flagX2 = X2, flagY2 = Y2;

	private void drawCompass(Graphics g) {
		// 绘制指南针
		int screenWidth = getWidth();
		g.setColor(0x8000ff00);
		g.drawRoundRect(screenWidth - 42, 7, 40, 40, 40, 40);
		g.setColor(0xff0000);
		g.setFont(Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
				Font.SIZE_MEDIUM));
		g.drawString("N", screenWidth - 25, 0, Graphics.TOP | Graphics.LEFT);
		g.drawString("W", screenWidth - 25, 40, Graphics.TOP | Graphics.LEFT);
		g.drawString("S", screenWidth - 44, 18, Graphics.TOP | Graphics.LEFT);
		g.drawString("E", screenWidth - 5, 18, Graphics.TOP | Graphics.LEFT);
		g.setColor(0x0000ff);
		g.drawLine(flagX1, flagY1, flagX2, flagY2);
		g.setColor(0xffff00);
		// g.fillTriangle(flagX1, flagY1, flagX1 - 3, flagY1 -3, flagX1 + 3,
		// flagY1 -3);
		g.fillRoundRect(flagX1 - 2, flagY1, 5, 5, 5, 5);
	}

	public static Image[] weapons = new Image[2];

	private static Image mainWeapon = MyGameMIDlet
			.makeImage("/weapons/AK47.png");

	public static void loadWeapons() {
		weapons[0] = MyGameMIDlet.makeImage("/weapons/AK47.png");
		weapons[1] = MyGameMIDlet.makeImage("/weapons/dagger.png");
	}

	// 在GameCanvas上绘制2D信息
	private void draw2D(Graphics g) {
		// text color
		StringBuffer status = new StringBuffer(finished ? "Done" : "");
		if (finished) {
			duration = System.currentTimeMillis() - gameStart;
			status.append(" Time:").append(duration / 1000);
		} else {
			status.append(" Time:");
			status.append((System.currentTimeMillis() - gameStart) / 1000);
		}

		// 绘制游戏时间(左上角)
		g.setColor(255, 255, 45);
		g.drawString(status.toString() + "Mem:" + Runtime.getRuntime().freeMemory() / 1024
				, 0, 0, Graphics.TOP | Graphics.LEFT);
		// 绘制FPS(左下角)
		g.setColor(45, 235, 45);
		g.drawString("FPS: " + fps, 0, getHeight(), Graphics.BOTTOM
				| Graphics.LEFT);
		// 绘制指南针(右上角)
		drawCompass(g);
		// 绘制自动准心
		if (!topView)
			drawAutoAimingRule(g);
		// 绘制手枪
		if (!topView)
			g.drawImage(mainWeapon, getWidth(), getHeight(), Graphics.BOTTOM
					| Graphics.RIGHT);
	}

	// 绘制自动准心
	private void drawAutoAimingRule(Graphics g) {
		int x = screen_width / 2;
		int y = screen_height / 2;
		g.setColor(0x00ff00);
		g.drawLine(x - 10, y, x - 4, y);
		g.drawLine(x + 10, y, x + 4, y);
		g.drawLine(x, y - 10, x, y - 4);
		g.drawLine(x, y + 10, x, y + 4);
	}

	// 绘制三位场景
	private void draw3D(Graphics g) {
		boolean bound = false;
		try {
			// binds the target
			g3d.bindTarget(g);
			bound = true;
			// advance the animation
			world.animate((int) (System.currentTimeMillis() - gameStart));
			// do the rendering
			g3d.render(world);
		} finally {
			// release the target
			if (bound) {
				g3d.releaseTarget();
			}
		}
	}

	public void run() {
		Graphics g = getGraphics();// 获得Graphics对象,注意Graphics3D对象必须绑定它才能绘制
		while (playing) {
			try {
				long startTime = System.currentTimeMillis();// 获取系统的当前时间作为每帧的初始时间
				if (isShown()) {// 如果游戏画布处于显示状态
					checkKeys();// 按键响应,与玩家进行交互
					long drawingTime = System.currentTimeMillis();
					draw3D(g);// 绘制3D部分
					drawingTime = System.currentTimeMillis() - drawingTime;
					fps = 1000 / drawingTime;// 计算每秒帧数
					draw2D(g);// 绘制2D部分
					flushGraphics();// 用缓冲区的内容刷新当前屏幕
				}
				long timeTaken = System.currentTimeMillis() - startTime;// 计算实际耗费的时间
				if (timeTaken < MILLIS_PER_TICK) {// 如果小于预计的时间戳,线程等待一定时间,保证帧频率稳定
					synchronized (this) {
						wait(MILLIS_PER_TICK - timeTaken);
					}
				} else {
					Thread.yield();// 否则将线程挂起
				}
			} catch (Exception e) {
				// ignore. Not much to but we want to keep the loop running
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -