有一个简单的浏览器内JS游戏需要它在后端'上使用Ruby脚本。

时间:2014-08-18 15:16:52

标签: javascript ruby html5 sinatra

我的'前端'是一个JS脚本,它加载一个HTML5画布并绘制一个X * Y网格,然后在网格中的某个默认(X,Y)坐标处绘制一个外星人。

我有一些红宝石类来定义这个外星人的动作。现在,它只是在X,Y平面上的+ - 。我希望能够点击浏览器中的“前进”按钮,然后向ruby脚本发送请求,然后计算新位置并发送带坐标的响应。

有人能指出我正确的方向吗?我无法理解这样做的逻辑。我读过Sinatra,AJAX,模板等,但没有任何帮助。

修改

app.rb

require 'sinatra'
require_relative 'alien'

get '/' do
  haml :home
end

get '/new_alien' do
  @alien = Alien.new 1,1,:N       # create a new alien
  @x = @alien.x                  # set the x coordinate
  @y = @alien.y                  # set the y coordinate
  %Q|{ "x":#{@x}, "y":#{@y} }|  # return a string with the coordinates
end

home.haml

!!!
%html
  %head
    %link{:rel => :stylesheet, :type => :"text/css", :href => "/css/main.css"}
  %body
    .wrapper
%script(src="http://code.jquery.com/jquery-2.1.1.min.js")
%script(src="/js/grid.js")

加载/路径时,应加载home.haml,我希望将xy值传递给使用这些坐标绘制的JS脚本一个图像。我不确定该怎么做。

1 个答案:

答案 0 :(得分:2)

1)使用javascript拦截按钮点击,方法是在按钮上安装onclick event handler

2)onclick event handler函数应使用javascript(或jquery)向服务器发送AJAX请求。 AJAX请求应包含服务器端ruby脚本生成其计算所需的任何相关数据。您的AJAX请求将指定某个网址,例如

"/calculate_new_position?x=10&y=20"

3)您的Sinatra应用程序位于服务器上,可以这么简单:

 require 'sinatra'

 get '/calculate_new_positon' do

    x_coord = params[:x]  #=> 10
    y_coord = params[:y]  #=> 20

    #Do calculation here:
    new_x = x_coord * 20  
    new_y = y_coord - 3

    #The following string is the response:
    %Q|{ "new_x":#{new_x}, "new_y":#{new_y} }| 

 end

当您的服务器收到网址/calculate_new_position?x=10&y=20的GET请求时,它将导致执行上面的代码。 Sinatra将自动在名为params的哈希中插入任何GET(或POST)变量。块的返回值将是the response,它将被发送回浏览器。

4)您的javascript AJAX代码将包含一个在收到服务器the response时调用的函数。该函数将包含以下内容:

obj = JSON.parse(json_str);  //--> obj = {"new_x":22, "new_y":-3};
new_x = obj["new_x"];
new_y = obj["new_y"];

#Use javascript to move figures to new coordinates.

以下是一个例子:

~/ruby_programs/sinatra_4app$ tree
.
├── models
│   └── alien.rb
├── public
│   └── js
│       └── grid.js
├── routes.rb
└── views
    └── home.haml

4 directories, 4 files

home.haml:

!!! 5
%html
  %body
    %button#forward_button Move forward

    %script{:type => "text/javascript",
      :src  => "http://code.jquery.com/jquery-2.1.1.min.js"}

    %script{:type => "text/javascript",
      :src  => "/js/grid.js"}

sinatra执行home.haml后的结果:

<!DOCTYPE html>
<html>
  <body>
    <button id='forward_button'>Move forward</button>
    <script src='http://code.jquery.com/jquery-2.1.1.min.js' type='text/javascript'></script>
    <script src='/js/grid.js' type='text/javascript'></script>
  </body>
</html>

routes.rb中:

require 'sinatra'
require_relative 'models/alien'

get '/' do
  haml :home, :format => :html5
  #Sinatra automatically looks for templates in a 'views' directory, so the line above looks for the file: views/home.haml
end

get '/new_alien' do
  alien = Alien.new 1,1,:N       
  alien.calculate_new_position
  new_x = alien.x
  new_y = alien.y

  %Q|{ "new_x":#{new_x}, "new_y":#{new_y} }|  #return a string in json format containing the new coordinates
end

alien.rb:

class Alien
  attr_accessor :x, :y, :direction

  def initialize(x, y, direction)
    @x = x
    @y = y
    @direction = direction
  end

  def calculate_new_position
    self.x += 2  #Changes @x using the accessor method rather than changing @x directly, which is considered good practice.
    self.y -= 2
  end
end

grid.js:

$(document).ready(function() {
                  #This function executes when all the html elements exist, i.e. when
                  #the document is 'ready'--you can't search for an element until it exists.

  #Search for an element whose id="forward_button" and install an event handler function 
  #for its onclick event:
  $("#forward_button").click(function() {
                             #This function executes when the button is clicked
    #Get current x, y coords somehow....
    var x = 10;
    var y = 20;

    var url = "/new_alien?x=" + x + "&y=" + y;

    $.getJSON(url, function(js_obj) {  #This is a specialized version of $.ajax()
                   #This function is called when the browser
                   #receives the response returned by the server

      new_x = js_obj["new_x"];
      new_y = js_obj["new_y"];
      #Do something with new_x and new_y...

      console.log( "Response received!" );
      console.log( "new_x= " + new_x);
      console.log( "new_y= " + new_y);
    });

  });

});

请注意,js注释以//开头,因此如果您不将#替换为//,则上述代码会导致错误。我使用#来获得浅灰色阴影,这使代码更容易阅读。

1)启动服务器:

~/ruby_programs/sinatra_4app$ ruby routes.rb 

2)然后在浏览器中输入以下网址:

http://localhost:4567/

3)然后打开控制台窗口,查看您使用的任何浏览器。在Firefox中,控制台窗口位于:

Tools>Web Developer>Web Console

在Chrome中,它是:

View>Developer>Javascript Console

4)点击&#34;前进&#34;按钮;然后在控制台窗口中检查输出。