From: Jean Privat Date: Thu, 10 Sep 2015 18:53:52 +0000 (-0400) Subject: Merge: nitcatalog: content and options X-Git-Tag: v0.7.8~33 X-Git-Url: http://nitlanguage.org?hp=4a477adc6165a8a8fc33f7ddc93ce2a9d25bdb24 Merge: nitcatalog: content and options Two improvements: * content list (example: see end of page , section *content*) * command-line options Pull-Request: #1699 Reviewed-by: Lucas Bajolet Reviewed-by: Alexis Laferrière --- diff --git a/examples/mnit_ballz/Makefile b/examples/mnit_ballz/Makefile index 337c69a..4120b52 100644 --- a/examples/mnit_ballz/Makefile +++ b/examples/mnit_ballz/Makefile @@ -1,4 +1,4 @@ -default: android +default: linux ../../contrib/inkscape_tools/bin/svg_to_icons: $(MAKE) -C ../../contrib/inkscape_tools @@ -7,6 +7,10 @@ android: icon mkdir -p bin ../../bin/nitc -o bin/ballz.apk src/ballz_android.nit +linux: + mkdir -p bin + ../../bin/nitc -o bin/ballz src/ballz_linux.nit + icon: ../../contrib/inkscape_tools/bin/svg_to_icons mkdir -p res ../../contrib/inkscape_tools/bin/svg_to_icons art/ball.svg --android --out res/ diff --git a/examples/mnit_ballz/assets/images/horizontal_wall.png b/examples/mnit_ballz/assets/images/horizontal_wall.png new file mode 100644 index 0000000..7ba6c68 Binary files /dev/null and b/examples/mnit_ballz/assets/images/horizontal_wall.png differ diff --git a/examples/mnit_ballz/assets/images/vertical_wall.png b/examples/mnit_ballz/assets/images/vertical_wall.png new file mode 100644 index 0000000..da42302 Binary files /dev/null and b/examples/mnit_ballz/assets/images/vertical_wall.png differ diff --git a/examples/mnit_ballz/res/raw/bounce.ogg b/examples/mnit_ballz/res/raw/bounce.ogg new file mode 100644 index 0000000..bcd66dd Binary files /dev/null and b/examples/mnit_ballz/res/raw/bounce.ogg differ diff --git a/examples/mnit_ballz/res/raw/walld.wav b/examples/mnit_ballz/res/raw/walld.wav new file mode 100644 index 0000000..f61d065 Binary files /dev/null and b/examples/mnit_ballz/res/raw/walld.wav differ diff --git a/examples/mnit_ballz/src/assets.nit b/examples/mnit_ballz/src/assets.nit new file mode 100644 index 0000000..e823284 --- /dev/null +++ b/examples/mnit_ballz/src/assets.nit @@ -0,0 +1,49 @@ +# this file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# All the assets needed by the appplication, regrouped in one class +module assets + +import app::audio +import mnit::assets + + +# Contains all the assets +class Assets + + # Sound for the wall destruction + var wall_destruction = new Sound("walld.wav") + + # Sound when the ball bounce + var bounce = new Sound("bounce.ogg") + + # Image of the ball + var ball: Image is noinit + + # Image for the horizontal walls + var horizontal_wall: Image is noinit + + # Image for the vertical walls + var vertical_wall: Image is noinit + + # Loads all the assets + fun load do + ball = app.load_image("images/ball.png") + horizontal_wall = app.load_image("images/horizontal_wall.png") + vertical_wall = app.load_image("images/vertical_wall.png") + wall_destruction.load + bounce.load + end +end diff --git a/examples/mnit_ballz/src/ballz_android.nit b/examples/mnit_ballz/src/ballz_android.nit index 249ee68..dc934e7 100644 --- a/examples/mnit_ballz/src/ballz_android.nit +++ b/examples/mnit_ballz/src/ballz_android.nit @@ -1,7 +1,5 @@ # this file is part of NIT ( http://www.nitlanguage.org ). # -# Copyright 2014 Romain Chanoir -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -14,22 +12,26 @@ # See the License for the specific language governing permissions and # limitations under the License. + +# Android part of mnit_ballz module ballz_android is - app_version(1, 0, git_revision) + app_version(0, 2, git_revision) app_name("Ballz") + app_namespace "org.nitlanguage.ballz" + android_api_target 19 end import android::portrait - -import game_logic +import android::sensors +import display +import mnit::android redef class App - var screen: nullable Screen + # The game + var game: nullable Game is noautoinit - redef fun run - do - sensors_support_enabled = true + redef fun run do accelerometer.enabled = true accelerometer.event_rate = 10000 magnetic_field.enabled = true @@ -37,33 +39,72 @@ redef class App light.enabled = true proximity.enabled = true maximum_fps = 50 - + sensors_support_enabled = true super end redef fun on_create do super - screen = new Screen(self, display.as(Display)) + game = new Game(display.width.to_f, display.height.to_f) end redef fun frame_core(display) do - var screen = self.screen - if screen != null then - screen.game.do_turn - screen.do_frame(display) + var game = game + if game != null then + game.do_turn + game.draw(display, assets) end end redef fun input(ie) - do - if ie isa QuitEvent then + do + if paused then return false + if ie isa QuitEvent then quit = true return true end - if screen != null then - return screen.input(ie) + var game = game + if game != null then + return game.input(ie) + end + return false + end +end + +redef class Ball + + redef fun intercepts(event) + do + if event isa ASensorAccelerometer then + acceleration(event.x, event.y) + else if event isa ASensorMagneticField then + #deal with Magnetic field sensor + #print "ASensorMagneticField : x = " + event.x.to_s + " y = " + event.y.to_s + " z = " + event.z.to_s + else if event isa ASensorGyroscope then + #deal with Gyroscope sensor + #print "ASensorGyroscope : x = " + event.x.to_s + " y = " + event.y.to_s + " z = " + event.z.to_s + else if event isa ASensorLight then + #deal with light sensor + #print "ASensorLight : light = " + event.light.to_s + else if event isa ASensorProximity then + #deal with proximity sensor + #print "ASensorProximity : distance = " + event.distance.to_s + else if event isa MotionEvent then + end + return true + end +end + + +redef class Game + + redef fun input(ie) + do + if ie isa ASensorAccelerometer or ie isa MotionEvent then + ball.intercepts(ie) + return true end return false end diff --git a/examples/mnit_ballz/src/ballz_linux.nit b/examples/mnit_ballz/src/ballz_linux.nit new file mode 100644 index 0000000..6f089a8 --- /dev/null +++ b/examples/mnit_ballz/src/ballz_linux.nit @@ -0,0 +1,104 @@ +# this file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Linux part of mnit_ballz +module ballz_linux + +import mnit::linux +import display + + +redef class App + + private var up_arrow_down = false + private var down_arrow_down = false + private var left_arrow_down = false + private var right_arrow_down = false + private var game: nullable Game is noautoinit + + redef fun run + do + maximum_fps = 50 + super + end + + redef fun on_create + do + super + game = new Game(display.width.to_f, display.height.to_f) + end + + redef fun frame_core(display) + do + if up_arrow_down then input(new SDLKeyEvent("up", true)) + if down_arrow_down then input(new SDLKeyEvent("down", true)) + if left_arrow_down then input(new SDLKeyEvent("left", true)) + if right_arrow_down then input(new SDLKeyEvent("right", true)) + + var game = game + if game != null then + game.do_turn + game.draw(display, assets) + end + end + + redef fun input(ie) + do + if ie isa QuitEvent then + quit = true + return true + end + var game = game + if game != null then + return game.input(ie) + end + return false + end +end + +redef class Ball + + redef fun intercepts(event) + do + var value = 5.0 + if event isa SDLKeyEvent then + if event.is_arrow_left then + acceleration(value, 0.0) + app.left_arrow_down = event.is_down + end + if event.is_arrow_right then + acceleration(-value, 0.0) + app.right_arrow_down = event.is_down + end + if event.is_arrow_up then + acceleration(0.0, -value) + app.up_arrow_down = event.is_down + end + if event.is_arrow_down then + acceleration(0.0, value) + app.down_arrow_down = event.is_down + end + end + return false + end +end + +redef class Game + + redef fun input(ie) + do + ball.intercepts(ie) + return false + end +end diff --git a/examples/mnit_ballz/src/collision.nit b/examples/mnit_ballz/src/collision.nit new file mode 100644 index 0000000..825cedc --- /dev/null +++ b/examples/mnit_ballz/src/collision.nit @@ -0,0 +1,87 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Geometric computations around vectors and points for collision detection +module collision + +import geometry + +# trigonometry + +# Get the distance between `p1` and `p2` +fun distance(p1, p2: Point[Float]): Float +do + var x = p1.x - p2.x + var y = p1.y - p2.y + return ( x * x + y * y ).sqrt +end + +# Get the magnitude (length) of `vector` +fun magnitude(vector: Point[Float]): Float do return ( vector.x * vector.x + vector.y * vector.y ).sqrt + +# Get the unit vector of `vector` +fun unit_vector(vector: Point[Float]): Point[Float] do return new Point[Float](vector.x / magnitude(vector), vector.y / magnitude(vector)) + +# Get the dot product of vectors `v1` and `v2` +fun dot_product(v1, v2: Point[Float]): Float do return v1.x * v2.x + v1.y * v2.y + +# Get the vector between `start_point` and `end_point` +fun vector_between(start_point, end_point: Point[Float]): Point[Float] do return new Point[Float](end_point.x - start_point.x, end_point.y - start_point.y) + +# Returns the point on a line with endpoints `l1` and `l2` closest to `center` +fun point_closest_to_line(center, l1, l2: Point[Float]): Point[Float] +do + var luvector = unit_vector(vector_between(l1, l2)) + var l_to_ball = vector_between(l1, center) + + var projection = dot_product(l_to_ball, luvector) + + if projection <= 0.0 then return l1 + if projection >= distance(l1, l2) then return l2 + return new Point[Float](l1.x + luvector.x * projection, l1.y + luvector.y * projection) +end + +# Is the ball with the `center` and `radius` intersecting the line with the endpoints `l1` and `l2`? +fun is_intersecting(center, l1, l2: Point[Float], radius: Float): Bool +do + var closest = point_closest_to_line(center, l1, l2) + var distance = distance(center, closest) + return distance < radius +end + +# Bouncing function, returns the new point of the center of the ball +fun bounce(center, l1, l2, offset: Point[Float]): Point[Float] +do + var bln = bounce_line_normal(center, l1, l2) + var dot = dot_product(offset, bln) + return new Point[Float](offset.x - (2.0 * dot * bln.x), offset.y - (2.0 * dot * bln.y)) +end + +private fun bounce_line_normal(center, l1, l2: Point[Float]): Point[Float] +do + var p = point_closest_to_line(center, l1, l2) + var v = vector_between(p, center) + return unit_vector(v) +end + +# Rotate `p` around `center` through `angle` +fun rotate_point(p, center: Point[Float], angle: Float): Point[Float] +do + var s = angle.sin + var c = angle.cos + + var nx = c * (p.x - center.x) - s * (p.y - center.y) + center.x + var ny = s * (p.x - center.x) + c * (p.y - center.y) + center.y + return new Point[Float](nx, ny) +end diff --git a/examples/mnit_ballz/src/display.nit b/examples/mnit_ballz/src/display.nit new file mode 100644 index 0000000..1d63189 --- /dev/null +++ b/examples/mnit_ballz/src/display.nit @@ -0,0 +1,47 @@ +# this file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Handles the drawing of all the game +module display + +import game_logic + +redef class Ball + + # Draw `self` onto `display` with image from `assets` + fun draw(display: Display, assets: Assets) + do + display.blit_centered(assets.ball, center.x, center.y) + end +end + +redef class Wall + + # Draw `self` onto `display` with image from `assets` + fun draw(display: Display, assets: Assets) + do + display.blit_rotated(assets.vertical_wall, center.x, center.y, angle) + end +end + +redef class Game + + # Draw all the entities onto `display` + fun draw(display: Display, assets: Assets) + do + display.clear (0.0, 0.0, 0.0) + ball.draw(display, assets) + for wall in walls do wall.draw(display, assets) + end +end diff --git a/examples/mnit_ballz/src/game_logic.nit b/examples/mnit_ballz/src/game_logic.nit index 7ece167..38d7682 100644 --- a/examples/mnit_ballz/src/game_logic.nit +++ b/examples/mnit_ballz/src/game_logic.nit @@ -1,7 +1,5 @@ #this file is part of NIT ( http://www.nitlanguage.org ). # -# Copyright 2014 Romain Chanoir -# # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -14,167 +12,172 @@ # See the License for the specific language governing permissions and # limitations under the License. +# All the logic of the game module game_logic -import mnit::android -import android::sensors +import assets +import objects +import geometry::quadtree +import collision -class Ball - var x: Float - var y: Float - var dim: Int - var walls_activated: Bool - var offset_x = 0.0 - var offset_y = 0.0 - var going_left: Bool - var going_down: Bool +redef class Ball - var game: Game + # Scale for drawing the image of `self` + var scale = 1.0 - init(game: Game, x,y: Float, walls: Bool) - do - self.x = x - self.y = y - self.dim = 20 - self.game = game - self.walls_activated = walls - end + # ASensorProximity value for modifying `scale` + # Not used yet + var scale_proximity_modifier = 6.0 + + # Radius of `self` + var radius = 32.0 + + # Movement vector of `self` + var offset = new Point[Float](0.0, 0.0) - # not very useful at this time - fun do_turn + # Calculates the acceleration of `self` + fun acceleration(x,y: Float) do + var max_offset = 10.0 + var max_value = 9.80 + var offset_x = offset.x - x/max_value + var offset_y = offset.y + y/max_value + if offset_x > max_offset then offset_x = max_offset + if offset_x < -max_offset then offset_x = -max_offset + if offset_y > max_offset then offset_y = max_offset + if offset_y < -max_offset then offset_y = -max_offset + offset = new Point[Float](offset_x, offset_y) end - fun intercepts(event: InputEvent): Bool + # Do the collision detection, then move `self`consequently + fun do_turn(game: Game) do - if event isa ASensorAccelerometer then - do_move(event) - else if event isa ASensorMagneticField then - #deal with Magnetic field sensor - print "ASensorMagneticField : x = " + event.x.to_s + " y = " + event.y.to_s + " z = " + event.z.to_s - else if event isa ASensorGyroscope then - #deal with Gyroscope sensor - print "ASensorGyroscope : x = " + event.x.to_s + " y = " + event.y.to_s + " z = " + event.z.to_s - else if event isa ASensorLight then - #deal with light sensor - print "ASensorLight : light = " + event.light.to_s - else if event isa ASensorProximity then - #deal with proximity sensor - print "ASensorProximity : distance = " + event.distance.to_s - else if event isa MotionEvent then - activate_walls(event) + offset = new Point[Float](offset.x * 0.98, offset.y * 0.98) + var np = collision(game.quadtree) + if np != null then + offset = np + center = new Point[Float](center.x + offset.x, center.y + offset.y) + else + center = new Point[Float](center.x + offset.x, center.y + offset.y) end - return true end - fun do_move (event: ASensorAccelerometer) + # Collision detection + fun collision(quadtree: SQuadTree[OrientedLine]): nullable Point[Float] do - # acceleration value - var vx = event.x - var vy = event.y - var gw = game.width - var gh = game.height - - # acceleration - var max_value = 9.80 - var acceleration_x = vx/max_value - var acceleration_y = vy/max_value - offset_x -= (acceleration_x/10.0)*(vx.abs) + offset_x/125.0 - offset_y += (acceleration_y/10.0)*(vy.abs) - offset_y/125.0 - var nx = self.x + offset_x - var ny = self.y + offset_y - going_left = offset_x > 0.0 - going_down = offset_y > 0.0 - - # x value - if nx >= 0.0 and nx <= gw then - self.x = nx - else if nx < 0.0 then - if not walls_activated then self.x = gw else do_bounce(1) - else if nx > gw then - if not walls_activated then self.x = 0.0 else do_bounce(1) + var nx = self.center.x + offset.x + var ny = self.center.y + offset.y + var new_center = new Point[Float](nx, ny) + var effective_radius = radius*scale + # Lines intersecting with the ball + var intersecting_lines = new Array[OrientedLine] + + # Line intersecting closest to the ball + var intersecting_line: nullable OrientedLine = null + + # closest point of the intersecting line + var closest_point: nullable Point[Float] = null + + # get the intersecting lines with help of the quadtree + var lines = quadtree.items_overlapping(new_center.padded(effective_radius)) + for l in lines do + if is_intersecting(new_center, l.point_left, l.point_right, effective_radius) then + intersecting_lines.add(l) + end end - # y value - if ny >= 0.0 and ny <= gh then - self.y = ny - else if ny < 0.0 then - if not walls_activated then self.y = gh else do_bounce(2) - else if ny > gh then - if not walls_activated then self.y = 0.0 else do_bounce(2) + # get the line closest to the ball from the intersecting lines, setting the closest point + var min_dist = 100.0 + if intersecting_lines.length >= 2 then + for l in intersecting_lines do + var closest = point_closest_to_line(new_center, l.point_left, l.point_right) + var distance = distance(closest, new_center) + if distance < min_dist then + min_dist = distance + intersecting_line = l + closest_point = closest + end + end + else if intersecting_lines.length == 1 then + intersecting_line = intersecting_lines[0] + closest_point = point_closest_to_line(new_center, intersecting_line.point_left, intersecting_line.point_right) end - end - # bounce in function of the position of the wall relative to the ball: 1=left or right, 2=top or down - fun do_bounce(wall_position: Int) - do - if wall_position == 1 then - offset_x = -offset_x*0.85 - else if wall_position == 2 then - offset_y = -offset_y*0.85 - end - if offset_x.abs > 1.0 and offset_y.abs > 1.0 then - self.x += offset_x - self.y += offset_y + if intersecting_line != null and closest_point != null then + return bounce(center, intersecting_line.point_left, intersecting_line.point_right, offset) end + return null end - fun activate_walls(event: MotionEvent) - do - if event.just_went_down then - walls_activated = not walls_activated - end - end + # Event interception + fun intercepts(event: InputEvent): Bool is abstract end -class Screen - var ball_img: Image - var game: Game - - init(app: App, display: Display) - do - game = new Game(display) - ball_img = app.load_asset("images/ball.png").as(Image) - var scale = game.img_dim.to_f / game.img_ori_dim.to_f - ball_img.scale = scale - ball_img.scale = 3.0 - end +# The core of the game +class Game - fun do_frame(display: Display) - do - display.clear(0.0, 0.0, 0.0) - display.blit_rotated(ball_img, game.ball.x, game.ball.y, 0.0) - end + # The Ball! + var ball: Ball is noinit - fun input(ie: InputEvent): Bool - do - if ie isa ASensorProximity then - if ie.distance == 0.0 then ball_img.scale = 6.0 else ball_img.scale = 3.0 - else - game.ball.intercepts(ie) - end - return true - end -end + # List of walls in the level + var walls: Array[Wall] is noinit -class Game - var ball: Ball + # Width of the display var width: Float + + # Heightof the display var height: Float - var img_ori_dim: Int = 256 - fun img_dim: Int do return 210 + # Quadtree used for collision detection + var quadtree: SQuadTree[OrientedLine] is noinit - init(display: Display) + init do - width = display.width.to_f - height = display.height.to_f - ball = new Ball(self, width/2.0, height/2.0, false) + ball = new Ball(new Point[Float](width/2.0, height/2.0)) + # Walls initialisation + var walla = new Wall(new Point[Float](width/4.0, height/4.0), pi/3.0, 1.0) + var wallb = new Wall(new Point[Float](width*0.75, height/4.0), 0.0, 1.0) + var wallc = new Wall(new Point[Float](width/4.0, height*0.75), 0.0, 1.0) + var walld = new Wall(new Point[Float](width*0.75, height*0.75), pi/3.0, 1.0) + walls = new Array[Wall].with_items(walla, wallb, wallc, walld) + + # adding screen bordures + var i = new Point[Float](0.0,0.0) + var a = new Point[Float](0.0, height/2.0) + var b = new Point[Float](width/2.0, 0.0) + var c = new Point[Float](width, height/2.0) + var d = new Point[Float](width/2.0, height) + + var l1 = new OrientedLine(i, i, pi/2.0, height, a) + var l2 = new OrientedLine(i, i, 0.0, width, b) + var l3 = new OrientedLine(i, i, pi/2.0, height, c) + var l4 = new OrientedLine(i, i, 0.0, width, d) + + quadtree = new SQuadTree[OrientedLine](5, width, height) + for w in walls do for l in w.lines do + quadtree.add(l) + end + quadtree.add(l1) + quadtree.add(l2) + quadtree.add(l3) + quadtree.add(l4) end - fun do_turn - do - ball.do_turn + # Only calls `do_turn` of the ball for the moment + fun do_turn do ball.do_turn(self) + + # Input gestion + fun input(ie: InputEvent): Bool do return false +end + +redef class App + + # Assets used in all the app + var assets = new Assets + + redef fun on_create do + super + assets.load end end diff --git a/examples/mnit_ballz/src/objects.nit b/examples/mnit_ballz/src/objects.nit new file mode 100644 index 0000000..d8e1686 --- /dev/null +++ b/examples/mnit_ballz/src/objects.nit @@ -0,0 +1,100 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Module containing all objects of the game +module objects + +import geometry +import geometry::polygon +import geometry::boxes +import collision + +# The ball is the main character of the game! +class Ball + # Center of the ball + var center: Point[Float] is writable +end + +# Walls make the ball bounce on them +class Wall + # Coordinates of the center of the wall + var center: Point[Float] + + # Angle in radian + var angle: Float + + # Scale for drawing `self` + var scale: Float + + # Width of `self` + var width: Float is noautoinit + + # Height of `self` + var height: Float is noautoinit + + # Lines composing `self` + var lines: Array[OrientedLine] is noautoinit + + # Initialize `self` with all its lines from `center` and `angle` + init do + self.height = 128.0 + self.width = 32.0 + var i = new Point[Float](0.0, 0.0) + var j = new Point[Float](0.0, 0.0) + + var a = new Point[Float]((center.x - width/2.0), center.y) + var b = new Point[Float]((center.x), (center.y - height/2.0)) + var c = new Point[Float]((center.x + width/2.0), center.y) + var d = new Point[Float]((center.x), (center.y + height/2.0)) + + var l1 = new OrientedLine(i, j, angle - pi/2.0, height * scale.to_f, rotate_point(a, center, angle)) + var l2 = new OrientedLine(i, j, angle, width * scale.to_f, rotate_point(b, center, angle)) + var l3 = new OrientedLine(i, j, angle - pi/2.0, height * scale.to_f, rotate_point(c, center, angle)) + var l4 = new OrientedLine(i, j, angle, width * scale.to_f, rotate_point(d, center, angle)) + lines = new Array[OrientedLine] + lines.add_all([l1, l2, l3, l4]) + end +end + +# A line represented with a center and an angle +class OrientedLine + super Line[Float] + redef type P: Point[Float] + + # Angle in radian + var angle: Float is writable + + # Length + var length: Float + + # Center + var center: Point[Float] + + redef fun point_left + do + var luv = unit_vector(new Point[Float](angle.cos, angle.sin)) + var offset_from_center = new Point[Float](luv.x * (length / 2.0), luv.y * (length / 2.0)) + return new Point[Float](center.x + offset_from_center.x, center.y + offset_from_center.y) + end + + redef fun point_right + do + var luv = unit_vector(new Point[Float](angle.cos, angle.sin)) + var offset_from_center = new Point[Float](luv.x * length / 2.0, luv.y * length / 2.0) + return new Point[Float](center.x - offset_from_center.x, center.y - offset_from_center.y) + end + + redef fun left do return point_left.x.min(point_right.x) + redef fun right do return point_left.x.max(point_right.x) +end diff --git a/lib/android/audio.nit b/lib/android/audio.nit index c70dd40..b729219 100644 --- a/lib/android/audio.nit +++ b/lib/android/audio.nit @@ -483,7 +483,7 @@ class MediaPlayer end redef class PlayableAudio - redef init do app.add_to_sounds(self) + redef init do add_to_sounds(self) end redef class Sound @@ -617,9 +617,6 @@ end redef class App - # Sounds handled by the application, when you load a sound, it's added to this list. - # This array is used in `pause` and `resume` - private var sounds = new Array[PlayableAudio] # Returns the default MediaPlayer of the application. # When you load a music, it goes in this MediaPlayer. @@ -676,12 +673,6 @@ redef class App return add_to_sounds(default_mediaplayer.load_sound(resource_manager.raw_id(music), self.native_activity)).as(Music) end - # Factorizes `sounds.add` to use it in `load_music`, `load_sound`, `load_music_from_res` and `load_sound_from_res` - private fun add_to_sounds(sound: PlayableAudio): PlayableAudio do - sounds.add(sound) - return sound - end - redef fun on_pause do super for s in sounds do s.pause @@ -700,3 +691,16 @@ redef class App for s in sounds do s.resume end end + +redef class Sys + + # Sounds handled by the application, when you load a sound, it's added to this list. + # This array is used in `pause` and `resume` + private var sounds = new Array[PlayableAudio] + + # Factorizes `sounds.add` to use it in `load_music`, `load_sound`, `load_music_from_res` and `load_sound_from_res` + private fun add_to_sounds(sound: PlayableAudio): PlayableAudio do + sounds.add(sound) + return sound + end +end diff --git a/lib/android/sensors.nit b/lib/android/sensors.nit index 3ee9765..b969389 100644 --- a/lib/android/sensors.nit +++ b/lib/android/sensors.nit @@ -20,19 +20,19 @@ # # ~~~~nitish # #FIXME rewrite the example -# var app = new MyApp -# app.sensors_support_enabled = true -# app.accelerometer.enabled = true -# app.accelerometer.eventrate = 10000 -# app.magnetic_field.enabled = true -# app.gyroscope.enabled = true -# app.light.enabled = true -# app.proximity.enabled = true -# app.main_loop +# redef class App +# sensors_support_enabled = true +# accelerometer.enabled = true +# accelerometer.eventrate = 10000 +# magnetic_field.enabled = true +# gyroscope.enabled = true +# light.enabled = true +# proximity.enabled = true +# end # ~~~~ # -# In this example, we enable the sensor support, then enable all types of sensors supported, before running the app. -# The result is you get all type of SensorEvent (ASensorAccelerometer, ASensorMagneticField ...) in the input method of your app +# In this example, we enable the sensor support, then enable all types of sensors supported by the API, directly with `App` attributes +# As a result, you get all type of SensorEvent (ASensorAccelerometer, ASensorMagneticField ...) in the `input` callback of `App` module sensors import android @@ -270,8 +270,8 @@ redef class App private fun enable_accelerometer do accelerometer.asensor = sensormanager.get_default_sensor(new ASensorType.accelerometer) - if accelerometer.asensor.address_is_null then - print "Accelerometer sensor unavailable" + if accelerometer.asensor.address_is_null then + print "Accelerometer sensor unavailable" else if eventqueue.enable_sensor(accelerometer.asensor) < 0 then print "Accelerometer enabling failed" eventqueue.set_event_rate(accelerometer.asensor, accelerometer.event_rate) @@ -314,7 +314,7 @@ redef class App private fun enable_proximity do proximity.asensor = sensormanager.get_default_sensor(new ASensorType.proximity) - if proximity.asensor.address_is_null then + if proximity.asensor.address_is_null then print "Proximity sensor unavailable" else if eventqueue.enable_sensor(proximity.asensor) < 0 then print "Proximity enabling failed" diff --git a/tests/sav/ballz_linux.res b/tests/sav/ballz_linux.res new file mode 100644 index 0000000..18bfeab --- /dev/null +++ b/tests/sav/ballz_linux.res @@ -0,0 +1,2 @@ +../lib/mnit/linux/linux_app.nit:29,16--31: Redef Error: a virtual type cannot be refined. +../lib/mnit/linux/linux_app.nit:30,16--29: Redef Error: a virtual type cannot be refined.