ag.import("std") function resetPins() local head_x = 0 local head_y = 15 local spacing = 0.7 for i = 1, 10 do if (pins[i] ~= nil) then pins[i]:destroy() end end local n = 1 for row = 0, 4 do for j = 0, row do pins[n] = reference_pin:clone() pins[n]:setPosition(head_x - row * spacing / 2 + j * spacing, head_y + 0.866 * spacing * row, 1 - pin_minz) end end end function setupStars() stars = ag.startList() local dist = 500 for i = 1, 500 do local rx = math.random() * math.pi * 2 local ry = (math.random() - 0.5) * math.pi * 0.8 local x = dist * math.cos(ry) * math.cos(rx) local y = dist * math.cos(ry) * math.sin(rx) local z = dist * math.sin(ry) local size = math.random(1, 6) ag.drawPoint(size, 1, 1, 1, x, y, z) end ag.endList() end function setupScore() current_frame = 1 current_ball = 1 score = {} for i = 1, 10 do local s = {} s[1] = 0 s[2] = 0 s["tot"] = 0 if (i == 10) then s[3] = 0 end score[i] = s end end function init_event() lane = ag.loadModelStatic("bowling_lane") local minx, miny, minz, maxx, maxy, maxz = lane:getAABB() local lane_bottom = minz pins = {} reference_pin = ag.loadModel("bowling_pin", 1.0/4.3) minx, miny, minz, maxx, maxy, maxz = reference_pin:getAABB() pin_minz = minz pin_maxz = maxz local box = ag.createBoxStatic(1, 10, 0.1) box:setVisible(false) box:setPosition(0, 0, lane_bottom - (maxz - minz) - 0.4) reference_pin:setPosition(0, 0, lane_bottom - maxz - 0.1) reference_ball = ag.createSphere(0.3) reference_ball:setColor(0.7, 0.1, 0.9) reference_ball:setMass(50) reference_ball:setPosition(0, -2, -1.5) resetPins() setupStars() setupScore() position_x = 0 target_x = 0 game_state = "waiting" last_update_time = ag.elapsedTime() end function update_event() ag.setCamera(position_x, -10, 5, target_x, 20, 0) local now = ag.elapsedTime() if (ag.isKeyDown("a") or ag.isKeyDown("left")) then position_x = position_x - (now - last_update_time) / 300 if (position_x < -2) then position_x = -2 end end if (ag.isKeyDown("d") or ag.isKeyDown("right")) then position_x = position_x + (now - last_update_time) / 300 if (position_x > 2) then position_x = 2 end end last_update_time = now ag.callList(stars) end function mouse_motion_event(x, y, xrel, yrel) target_x = target_x + xrel / 100 if (target_x < -2) then target_x = -2 elseif (target_x > 2) then target_x = 2 end end function drawFrameScore(width, height, frame, fs) local size = 60 local ball_size = 24 local local_width = size if (frame == 10) then local_width = 80 end local base_x = size / 2 + size * (frame - 1) local base_y = height - size / 2 - size ag.drawRect(1, 0.6, 0, local_width, size, base_x + local_width / 2, base_y + size / 2) ag.drawRect(1, 0.6, 0, ball_size, ball_size, base_x + local_width - ball_size / 2, base_y + size - ball_size / 2) if (frame == 10) then ag.drawRect(1, 0.6, 0, ball_size, ball_size, base_x + local_width - ball_size * 1.5, base_y + size - ball_size / 2) end local balls = 2 if (frame == 10) then balls = 3 end for ball = 1, balls do if ((frame < current_frame) or (frame == current_frame and ball < current_ball)) then local ball_base_x = base_x + local_width - (1 + balls - ball) * ball_size + 7 local ball_base_y = base_y + size - ball_size + 7 ag.drawText(fs[ball], 1, 0.6, 0, 14, ball_base_x, ball_base_y) if (frame < current_frame and fs["tot"] ~= 0) then local w, h = ag.getTextSize(fs["tot"], 16) ag.drawText(fs["tot"], 1, 0.6, 0, 16, base_x + local_width - 10 - w, base_y + 10) end end end end function drawScore(width, height) ag.drawText("Score:", 1, 0.6, 0, 16, 30, height - 25) for i = 1, 10 do drawFrameScore(width, height, i, score[i]) end end function update_overlay_event(width, height) drawScore(width, height) if (game_state == "get_power" or game_state == "launched") then drawPowerBar(width, height) end end function mousebutton_down_event(button, x, y) if (button == 1) then if (game_state == "waiting") then getPower() elseif (game_state == "get_power") then launchBall() end end end function getPower() game_state = "get_power" power = 0 power_last_time = ag.elapsedTime() power_direction = 1 end function launchBall() game_state = "launched" launch_time = ag.elapsedTime() bowling_ball = reference_ball:clone() bowling_ball:setPosition(position_x, -10, 4) end function drawPowerBar(width, height) local bar_width = 80 local bar_height = 400 if (game_state == "get_power") then local now = ag.elapsedTime() power = power + (now - power_last_time) / 250 * power_direction if (power > 1) then power = 1 power_direction = -1 elseif (power < 0) then power = 0 power_direction = 1 end power_last_time = now end ag.drawRect(1, 1, 1, bar_width, bar_height, width - 50 - bar_width / 2, height / 2) ag.fillRect(0.1, 1, 0.1, bar_width - 2, (bar_height - 2) * power, width - 50 - bar_width / 2, height / 2) end