做一款属于自己的体感游戏

来源:互联网 发布:淘宝店铺活动怎么删除 编辑:程序博客网 时间: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();}


如果大家需要完整代码可以在评论里给我留言。另外,不放图片似乎会显得没有诚意,下面就放一张PC端程序运行的效果图:




0 0
原创粉丝点击