Skip to content

Instantly share code, notes, and snippets.

@gkbrk
Created January 8, 2016 21:28
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save gkbrk/01f30b1f2b983a142d8a to your computer and use it in GitHub Desktop.
Save gkbrk/01f30b1f2b983a142d8a to your computer and use it in GitHub Desktop.
Simple idle clicker game in Rust
#[macro_use] extern crate conrod;
extern crate find_folder;
extern crate piston_window;
use conrod::{Labelable, Positionable, Sizeable, Colorable, Theme, Ui, Widget};
use conrod::color;
use piston_window::{EventLoop, Glyphs, PistonWindow, UpdateEvent, WindowSettings};
struct GameState {
coins: u64,
miners: u64,
multiplier: u64,
llvm_optimizations: u64
}
impl GameState {
pub fn new() -> GameState {
return GameState {
coins: 0,
miners: 0,
multiplier: 1,
llvm_optimizations: 1
};
}
pub fn add_coins(&mut self, amount: u64) {
self.coins += amount;
}
pub fn manual_mine(&mut self) {
let mult = self.multiplier;
let llvm = self.llvm_optimizations;
let total_amount = mult.pow(2) + llvm.pow(4);
self.add_coins(total_amount);
}
pub fn tick_second(&mut self) {
let miners = self.miners;
let mult = self.multiplier;
self.add_coins(miners * mult);
}
pub fn miner_price(&self) -> u64 {
return self.miners.pow(3);
}
pub fn multiplier_price(&self) -> u64 {
return 7u64.pow(self.multiplier as u32);
}
pub fn llvm_price(&self) -> u64 {
return 10u64.pow(self.llvm_optimizations as u32);
}
}
fn main() {
let window: PistonWindow = WindowSettings::new("Rust Clicker", [400, 270]).build().unwrap();
let mut ui = {
let assets = find_folder::Search::KidsThenParents(3, 5).for_folder("assets").unwrap();
let font_path = assets.join("fonts/NotoSans/NotoSans-Regular.ttf");
let theme = Theme::default();
let glyph_cache = Glyphs::new(&font_path, window.factory.borrow().clone());
Ui::new(glyph_cache.unwrap(), theme)
};
let mut game = GameState::new();
let mut button_color = color::random();
let mut bg_hue = 0.0f32;
let mut colorful_mode = false;
let mut deltatime_total: f64 = 0.0;
for event in window.ups(30) {
ui.handle_event(&event);
event.update(|args| ui.set_widgets(|ui| {
widget_ids!(MINE_BUTTON,
MINER_BUTTON,
MULTIPLIER_BUTTON,
LLVM_BUTTON,
COLORFULMODE_BUTTON,
COINS_TEXT);
let x_zero = -(ui.win_w/2.0);
let y_zero = ui.win_h/2.0;
deltatime_total += args.dt;
if deltatime_total > 0.10 {
game.tick_second();
deltatime_total = deltatime_total - 0.10;
}
if colorful_mode {
bg_hue += args.dt as f32 / 2.0;
bg_hue = bg_hue % 6.28;
conrod::Background::new()
.hsl(bg_hue, 0.35, 0.5)
.set(ui);
}else {
conrod::Background::new()
.set(ui);
}
conrod::Button::new()
.x(x_zero + 50.0)
.y(y_zero - 50.0)
.dimensions(80.0, 80.0)
.label("Mine!")
.color(button_color)
.react(|| {
game.manual_mine();
button_color = color::random();
})
.set(MINE_BUTTON, ui);
conrod::Button::new()
.right(20.0)
.dimensions(270.0, 45.0)
.label(format!("Buy auto-miner (${})", game.miner_price()).trim())
.enabled(game.coins > game.miner_price())
.react(|| {
game.coins -= game.miner_price();
game.miners += 1;
})
.set(MINER_BUTTON, ui);
conrod::Button::new()
.down(10.0)
.dimensions(270.0, 45.0)
.label(format!("Buy multiplier (${})", game.multiplier_price()).trim())
.enabled(game.coins > game.multiplier_price())
.react(|| {
game.coins -= game.multiplier_price();
game.multiplier += 1;
})
.set(MULTIPLIER_BUTTON, ui);
conrod::Button::new()
.down(10.0)
.dimensions(270.0, 45.0)
.label(format!("Optimize LLVM (${})", game.llvm_price()).trim())
.enabled(game.coins > game.llvm_price())
.react(|| {
game.coins -= game.llvm_price();
game.llvm_optimizations += 1;
})
.set(LLVM_BUTTON, ui);
conrod::Button::new()
.down(10.0)
.dimensions(270.0, 45.0)
.label("Toggle Rainbows ($100,000)")
.enabled(game.coins > 100_000)
.react(|| {
colorful_mode = !colorful_mode;
game.coins -= 100_000;
})
.set(COLORFULMODE_BUTTON, ui);
conrod::Text::new(&format!("{} RustCoins", game.coins))
.down(20.0)
.align_text_left()
.rgb(255.0, 255.0, 255.0)
.set(COINS_TEXT, ui);
}));
event.draw_2d(|c, g| ui.draw_if_changed(c, g));
}
}
@mitchmindtree
Copy link

Nice! Really cool to see conrod used live like this, was very interesting to see.

One small recommendation that I would make is to remove the x_zero and y_zero locals and instead position the first Button using the "placement" methods to get the same behaviour. So instead of this

let x_zero = -(ui.win_w/2.0);
let y_zero = ui.win_h/2.0;
conrod::Button::new()
    .x(x_zero + 50.0)
    .y(y_zero - 50.0)

you could do this

conrod::Button::new()
    .top_left_with_margin(50.0)

I realise this was just a quick project, but just thought I'd share anyway :) Also, the method was only added recently, so it might not have been available to you at the time.

@Anonymus1
Copy link

Where did you learn conrod?

@AurevoirXavier
Copy link

AurevoirXavier commented Dec 14, 2018

New version here, similar to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment