做一款属于自己的体感游戏
来源:互联网 发布:淘宝店铺活动怎么删除 编辑:程序博客网 时间:2024/04/29 08:30
体感游戏这个概念大家应该不陌生,不过要自己编一个体感游戏似乎有些困难,主要是人体动作的获取比较令人头疼。不过,智能手机的出现让这件事情变得简单了许多。现在我们用的手机里都有许多传感器,例如三轴加速度计,利用这些传感器就可以实现体感游戏的编写。
系统构架是这样的:
手机传感器信息采集——利用算法进行模式识别——利用wifi或蓝牙传给PC——实现PC游戏程序的操控
看起来并不复杂,是吗?我用了不到3个小时就编出了一个demo。传感器用的是Android手机上的三轴加速度计,通信是用的socket,PC上的游戏程序是用Qt现编的贪吃蛇,实现的功能是手持手机,通过手的运动来操控贪吃蛇。闲话不多说,下面放出关键代码:
首先是Android代码,主要是传感器数据采集、socket通信(不要忘记添加网络权限)。用的模式识别非常简单,直接判断某个方向上加速度的大小来辨别方向:
MainActivity.java
package com.example.test;import java.io.IOException;import java.net.Socket;import java.net.UnknownHostException;import java.util.List;import android.app.Activity;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends Activity {private SensorManager sm;private mylistener ml;private Socket so; protected void onCreate(Bundle savedInstanceState) { sm = (SensorManager)getSystemService(SENSOR_SERVICE); List<Sensor> kkk = sm.getSensorList(Sensor.TYPE_ALL); ml = new mylistener(); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView c = (TextView)(findViewById(R.id.view));String s = ""; for (int i = 0;i < kkk.size();++i) s += kkk.get(i).getName() + '\n'; c.setText(s); new Thread() { public void run(){ try {so = new Socket("192.168.1.104", 12345);} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} } }.start(); } @Override protected void onResume() {Sensor sensor_orientation=sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); sm.registerListener(ml,sensor_orientation, SensorManager.SENSOR_DELAY_GAME); super.onResume(); } @Override protected void onPause() { sm.unregisterListener(ml); super.onPause(); } private final class mylistener implements SensorEventListener { @Override public void onSensorChanged(SensorEvent event) { TextView cc = (TextView)(findViewById(R.id.view2));// TODO Auto-generated method stub if (event.sensor.getType()==Sensor.TYPE_ACCELEROMETER) { float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; cc.setText("x: "+x+"\ny: "+y+"\nz: "+z); if (x < -5) {try {so.getOutputStream().write('1');} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} } if (x > 5) {try {so.getOutputStream().write('0');} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} } if (z < -5) {try {so.getOutputStream().write('2');//} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} } if (z > 5) {try {so.getOutputStream().write('3');} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // TODO Auto-generated method stub } }}
下面是PC端用Qt写的代码,很简单的一个贪吃蛇,可以用上下左右键操控,按s重新开始,为了用手机操控还要加上socket通信:
首先是头文件:
server.h
#ifndef SERVER_H#define SERVER_H#endif // SERVER_H#include <QObject>#include <QWidget>#include <QTcpServer>#include <QTcpSocket>class MyPainter:public QWidget{ Q_OBJECT int **board; int **from_x; int **from_y; int b_w; int b_l; int size; int head_x; int head_y; int tail_x; int tail_y; int len; QTimer *timer; int status;public: int dir; int temp_dir; MyPainter(); ~MyPainter(); void InitGame(); void paintEvent(QPaintEvent *e); void keyPressEvent(QKeyEvent *e); void RandomFood();public slots: void SnakeMove();};class Server: public QObject{ Q_OBJECTprivate: QTcpServer *server; QTcpSocket *socket; MyPainter *mp;public: Server(); ~Server();public slots: void getSocket(); void print();};接下来是主程序:
main.cpp
#include <QApplication>#include <server.h>#include <QPainter>#include <QKeyEvent>#include <ctime>#include <QTimer>#define Form2Darray(dd) \ dd = new int*[b_w];\ for (int i = 0;i < b_w;++i)\ dd[i] = new int[b_l];#define Destroy2Darray(dd) \ for (int i = 0;i < b_w;++i)\ delete[] dd[i];\ delete[] dd;#define FOOD 2#define EMPTY 0#define BODY 1Server::Server(){ server = new QTcpServer(); server->listen(QHostAddress::Any, 12345); QObject::connect(server, SIGNAL(newConnection()), this, SLOT(getSocket())); mp = new MyPainter(); mp->show();}void Server::getSocket(){ socket = server->nextPendingConnection(); QObject::connect(socket, SIGNAL(readyRead()), this, SLOT(print()));}void Server::print(){ QByteArray content= socket->readAll(); if (content[0] == '1') if (mp->dir != 0) mp->temp_dir = 1; if (content[0] == '0') if (mp->dir != 1) mp->temp_dir = 0; if (content[0] == '3') if (mp->dir != 2) mp->temp_dir = 3; if (content[0] == '2') if (mp->dir != 3) mp->temp_dir = 2; qDebug() << content;}Server::~Server(){ delete server;}MyPainter::MyPainter(){ b_w = 25; b_l = 20; size = 20; timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(SnakeMove())); Form2Darray(board) Form2Darray(from_x) Form2Darray(from_y) InitGame();}MyPainter::~MyPainter(){ Destroy2Darray(board) Destroy2Darray(from_x) Destroy2Darray(from_y)}void MyPainter::InitGame(){ status = 1; //begin head_x = b_w/2+1; head_y = b_l/2-1; tail_x = b_w/2-1; tail_y = b_l/2-1; dir = 2; temp_dir = 2; len = 3; for (int i = 0;i < b_w;++i) for (int j = 0;j < b_l;++j) board[i][j] = 0; board[b_w/2-1][b_l/2-1] = 1; board[b_w/2][b_l/2-1] = 1; board[b_w/2+1][b_l/2-1] = 1; from_x[b_w/2][b_l/2-1]=b_w/2+1; from_y[b_w/2][b_l/2-1]=b_l/2-1; from_x[b_w/2-1][b_l/2-1]=b_w/2; from_y[b_w/2-1][b_l/2-1]=b_l/2-1; srand((unsigned) time(NULL)); RandomFood(); timer->start(300);}void MyPainter::SnakeMove(){ dir = temp_dir; int dir_x[4] = {0, 0, 1, -1};//down up right left int dir_y[4] = {1, -1, 0, 0}; int nx = head_x + dir_x[dir]; int ny = head_y + dir_y[dir]; if (nx >=0 && nx < b_w && ny >= 0 && ny < b_l && status==1) { if (board[nx][ny] != BODY) { from_x[head_x][head_y] = nx; from_y[head_x][head_y] = ny; if (board[nx][ny] != FOOD) { board[tail_x][tail_y] = EMPTY; int t_tail_x = from_x[tail_x][tail_y]; int t_tail_y = from_y[tail_x][tail_y]; tail_x = t_tail_x; tail_y = t_tail_y; } else { RandomFood(); ++len; } head_x = nx; head_y = ny; board[nx][ny] = BODY; this->update(); return; } } status = 0; qDebug() << "game over! The lenght of SNAKE is " << len << '\n'; timer->stop(); //game over:}void MyPainter::RandomFood(){ while(1) { int x = rand() % b_w; int y = rand() % b_l; if (board[x][y] == EMPTY) { board[x][y] = FOOD; break; } }}void MyPainter::paintEvent(QPaintEvent *e){ QPainter *pa; pa = new QPainter(); pa->begin(this); for (int i = 0;i < b_w;++i) for (int j = 0;j < b_l;++j) { pa->setBrush(Qt::transparent); if (board[i][j] == BODY) pa->setBrush(Qt::black); if (board[i][j] == FOOD) pa->setBrush(Qt::red); pa->drawRect(50+i*size, 50+j*size, size-3, size-3); } pa->end(); delete pa;}void MyPainter::keyPressEvent(QKeyEvent *e){ if (e->key() == Qt::Key_Up) if (dir != 0) temp_dir = 1; if (e->key() == Qt::Key_Down) if (dir != 1) temp_dir = 0; if (e->key() == Qt::Key_Left) if (dir != 2) temp_dir = 3; if (e->key() == Qt::Key_Right) if (dir != 3) temp_dir = 2; if (e->key() == Qt::Key_S && status == 0) InitGame();}int main(int argc, char *argv[]){ QApplication a(argc, argv); Server x; QTcpSocket client; client.connectToHost("127.0.0.1", 12345); client.write("haha"); return a.exec();}
0 0
- 做一款属于自己的体感游戏
- 自己做一款游戏
- 想做属于自己的三国类的游戏
- 打造一款属于自己的Android滑动器
- Android——写一款属于自己的天气预报
- 一起来做属于自己的PHP项目
- 做一个属于自己的照片编辑器
- 怎么做一款赚钱的iPhone游戏
- 想起当年自己写的一款游戏
- “数字签名”自己做打造属于自己的在线工具
- 我写一个游戏,属于自己的游戏
- 搭建自己的NAS存储之 - 选择一款属于自己NAS 系统
- 使用debootstrap做一个属于自己的系统
- 我为什么要选择做一个属于自己的网站!
- 【转】使用debootstrap做一个属于自己的系统(zh)
- 解析-做一个属于自己(企业)的网站
- 如何设计属于自己的游戏服务器(一)
- 如何设计属于自己的游戏服务器(二)
- 十一、类的静态成员
- Windows7建立共享WiFi设置(局域网配置)
- 5、工厂方法模式(FactoryMethod)
- 观察者模式
- OC中类的封装
- 做一款属于自己的体感游戏
- VMware网络连接方式(Host-only、NAT、Bridged)介绍及NAT环境下静态IP配置
- iOS-UIResponse之事件响应链及其事件传递
- 动态规划之最长上升子序列
- ACM学习-动态规划-物品供应问题
- 【Linux导论】查找Linux文档(Finding Linux Documentation)
- Ubuntu 出现apt-get: Package has no installation candidate问题
- iOS开发如何让透明View里的对象不透明
- windwos 2008 R2 hype-v